我试图在我的Groovy代码中覆盖java类型实例的方法的功能,但我得到一个classcast异常。
我查看了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无法强制转换为 java.lang.CharSequence at example.main(test.groovy:12)
那么,关于我做错了什么或者是否有另一种方法来解决我添加和/或覆盖java类型实例的方法的问题的任何想法?
我使用的是Groovy 1.7.4版。
答案 0 :(得分:2)
您正在为java.lang.String
创建ExpandoMetaClass,但将其分配给groovy.util.Proxy
。为groovy.util.Proxy
instread创建一个metaClass,如下所示:
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)
答案 1 :(得分: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)
}