Is it possible to use Groovy to override a method in a Java class, when that Java class is not instantiated in my code?

不问归期 提交于 2019-12-22 08:56:13

问题


I am developing an Eclipse RCP application and I recently started to use Groovy in it. So 99% of my code is still Java.

I read that it is possible to use Groovy to override and add methods to Java classes and I was able to test this by adding a method to the java.lang.String.

But this only works when I use the string in a Groovy class. The overridden method is not considered as being overridden in a Java class.

Here's some code:

/*
 * This is a Java class
 */
public class CTabItem {
   ...
   private API
   ...
   public void setControl(Control control){
       private API
   }
}

/*
 * This is also a Java class
 */
public class Control {
   ...
   private API
   ...
}

/*
 * This is also a Java class
 */
public class OtherClass {
  ...
  private API
  ...
  private void someMethodIDontKnow(){
     Control control = new Control();
     CTabItem tab = new CTabItem();
     tab.setControl(control);
  }
}

/*
 * This is a Groovy class
 */
public class MyViewPart extends org.eclipse.ui.part.ViewPart {
     ....
     public void createPartControl(Composite parent) {
          /* parent (or the parent of parent) is a Control
           which is set somewhere in a CTabItem to which
           I don't get access  */
     }        
}

I need to get the tab from the control. But since it's not me who instantiates MyViewPart, but some private API, I have no access to it. Is there something Groovy could do for me here? Any suggestion or code is welcome. Thank you!


回答1:


The short answer is: no, it's not possible if the code creating the object and calling the method is pure Java (i.e., non-Groovy) code. Groovy does its magic by intercepting all method calls on objects (both Java objects and Groovy objects) and using its ExpandoMetaClass to add the behavior. However, it can't change how pure Java code determines which method to call on a pure Java class. To see, run the following sample code:

// UseTheString.java (a pure Java class)
public class UseTheString {
    public static void main(String[] arg) {
        String s = "Hello world";
        System.out.println(s);
        System.out.println(s.substring(1));
        ModifyStringClass.messWithMetaClasses(s);
        System.out.println(s.substring(1));
    }
}

and

// ModifyStringClass.groovy (a Groovy class)
class ModifyStringClass {
    public static messWithMetaClasses(String t) {
        java.lang.String.metaClass.substring = { int n -> "!" }
        println(t.substring(1))
    }
}

You'll get the output:

Hello world
ello world
!
ello world

As you can see, Groovy can override the method on a pure Java object if it is called from other Groovy code, but it can't change how the Java code uses it.



来源:https://stackoverflow.com/questions/15884190/is-it-possible-to-use-groovy-to-override-a-method-in-a-java-class-when-that-jav

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!