2010-10-27 77 views
1

我想在我的Groovy代码中重写java类型实例的方法的功能,但我得到一个classcast异常。如何用Groovy元编程重写java类型实例的方法?

我看着指南贴here,但我不能得到它的工作。

由于我的实际问题有点混乱,下面是一些可运行的示例代码,失败时会出现相同的错误。 在这个例子中,我想覆盖java.lang.String类的实例的substring方法。实际上,我想重写一个没有相应Groovy实现的类的实例的方法,因此我的示例的答案不是简单地使用Groovy字符串实例。

class example { 
    static void main(args) { 
     java.lang.String hey = new java.lang.String("hey") 
     ExpandoMetaClass emc = new ExpandoMetaClass(java.lang.String, false) 
      emc.substring = { 
         "This is not a very good substring implementation" 
       } 
      emc.initialize() 

     def proxiedHey = new groovy.util.Proxy().wrap(hey) 
     proxiedHey.setMetaClass(emc) 
     printf proxiedHey.toString() 
     printf proxiedHey.substring(1) 
    } 
} 

上述示例在第12行失败,即printf meh.toString()。抛出的异常是

夹缝:java.lang.ClassCastException: groovy.util.Proxy不能在 example.main(test.groovy:12)被转换为 java.lang.CharSequence中

那么,我做什么错误的任何想法,或者如果有另一种方法来解决我的java类型实例的方法添加和/或重写的问题?

我正在使用Groovy版本1.7.4。

回答

2

您正在为java.lang.String创建ExpandoMetaClass,但将其分配给groovy.util.Proxy。让元类为groovy.util.Proxy instread,就像这样:

java.lang.String hey = new java.lang.String("hey") 
def proxiedHey = new groovy.util.Proxy().wrap(hey) 
ExpandoMetaClass emc = new ExpandoMetaClass(groovy.util.Proxy, false) 
emc.substring = { 
    "This is not a very good substring implementation" 
} 
emc.initialize() 

proxiedHey.setMetaClass(emc) 
printf proxiedHey.toString() 
printf proxiedHey.substring(1) 
+0

感谢您的及时正确的回复! – John 2010-11-04 13:11:36

0

你看着Pimp my Library Pattern它允许你使用Groovy Categories补充。您可能会发现在您的案例中更方便,更易于理解。

@Category(String) 
class StringSubstrCategory {  
    def substring(int n) { 
     "This is not a very good substring implementation" 
    } 
} 

use (StringSubstrCategory) { 
    "hey".substring(1) 
}