当我的代码中没有实例化Java类时,是否可以使用Groovy覆盖Java类中的方法? [英] Is it possible to use Groovy to override a method in a Java class, when that Java class is not instantiated in my code?

查看:115
本文介绍了当我的代码中没有实例化Java类时,是否可以使用Groovy覆盖Java类中的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我读到可以使用Groovy来覆盖和添加Java类的方法,我能够通过向java.lang.String添加一个方法。



但是,只有当我使用Groovy类中的字符串时,这才有效。覆盖的方法不被认为是在Java类中被覆盖。



这里有一些代码:

  / * 
*这是一个Java类
* /
public class CTabItem {
...
private API
...
public void setControl(Control control){
private API
}
}

/ *
*这也是一个Java类
* /
public class Control {
...
private API
...
}

/ *
*这也是一个Java类
* /
public class OtherClass {
...
private API
...
private void someMethodIDontKnow(){
Control control = new Control();
CTabItem tab = new CTabItem();
tab.setControl(control);
}
}

/ *
*这是一个Groovy类
* /
public class MyViewPart extends org.eclipse.ui。 part.ViewPart {
....
public void createPartControl(Composite parent){
/ * parent(或父代的父项)是一个Control
,它设置在某处一个CTabItem,
我没有访问* /
}
}

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

解决方案

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

  // UseTheString.java(纯Java类)
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;
System.out.println(s.substring(1));
}
}

  // ModifyStringClass.groovy(一个Groovy类)
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可以覆盖纯Java对象上的方法如果它是从其他Groovy代码调用的,但是它不能改变Java代码如何使用它。


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!

解决方案

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.

这篇关于当我的代码中没有实例化Java类时,是否可以使用Groovy覆盖Java类中的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆