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

我正在开发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 */ } } 

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

简短的回答是:不,如果创建对象并调用该方法的代码是纯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)); } } 

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

你会得到输出:

 Hello world ello world ! ello world 

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