当我的代码中没有实例化Java类时,是否可以使用Groovy覆盖Java类中的方法?

Ale*_*lex 4 java eclipse groovy rcp eclipse-rcp

我正在开发Eclipse RCP应用程序,最近我开始在其中使用Groovy.所以99%的代码仍然是Java.

我读到可以使用Groovy覆盖并向Java类添加方法,我可以通过向java.lang.String添加一个方法来测试它.

但这仅在我在Groovy类中使用字符串时才有效.重写的方法不被视为在Java类中被重写.

这是一些代码:

/*
 * 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  */
     }        
}
Run Code Online (Sandbox Code Playgroud)

我需要从控件中获取选项卡.但是,由于我不是谁实例化MyViewPart,而是一些私有API,我无法访问它.Groovy能为我做些什么吗?欢迎任何建议或代码.谢谢!

Tom*_*ing 11

简短的回答是:不,如果创建对象并调用该方法的代码是纯Java(即非Groovy)代码,则不可能.Groovy通过拦截对象(Java对象和Groovy对象)上的所有方法调用并使用其ExpandoMetaClass来添加行为来实现其魔力.但是,它无法改变纯Java代码如何确定在纯Java类上调用哪个方法.要查看,请运行以下示例代码:

// 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));
    }
}
Run Code Online (Sandbox Code Playgroud)

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

你会得到输出:

Hello world
ello world
!
ello world
Run Code Online (Sandbox Code Playgroud)

如您所见,如果从其他Groovy代码调用它,Groovy可以覆盖纯Java对象上的方法,但它不能改变Java代码使用它的方式.