【问题标题】:Groovy runtime method interceptionGroovy 运行时方法拦截
【发布时间】:2012-08-29 23:57:21
【问题描述】:
我在玩 Groovy,我想知道,为什么这段代码不起作用?
package test
interface A {
void myMethod()
}
class B implements A {
void myMethod() {
println "No catch"
}
}
B.metaClass.myMethod = {
println "Catch!"
}
(new B()).myMethod()
它打印出No catch,而我希望它打印出Catch!。
【问题讨论】:
标签:
groovy
metaclass
interception
method-invocation
【解决方案1】:
有一种解决方法,但它仅适用于所有类,而不适用于特定实例。
在构造之前修改元类:
interface I {
def doIt()
}
class T implements I {
def doIt() { true }
}
I.metaClass.doIt = { -> false }
T t = new T()
assert !t.doIt()
构建后的元类修改:
interface I {
def doIt()
}
class T implements I {
def doIt() { true }
}
T t = new T()
// Removing either of the following two lines breaks this
I.metaClass.doIt = { -> false }
t.metaClass.doIt = { -> false }
assert !t.doIt()
【解决方案2】:
这是 Groovy 中的一个错误,JIRA 中有一个未解决的问题:无法通过作为接口实现一部分的元类覆盖方法,GROOVY-3493。
【解决方案3】:
不要重写 B.metaClass.myMethod,而是尝试以下操作:
B.metaClass.invokeMethod = {String methodName, args ->
println "Catch!"
}
这个blog post描述得很好。