Groovy运行时方法拦截

时间:2012-09-05 09:37:08

标签: groovy metaclass interception method-invocation

我正在玩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!

3 个答案:

答案 0 :(得分:9)

这是Groovy中的一个错误,JIRA中存在一个未解决的问题:无法通过作为接口实现的一部分的元类覆盖方法GROOVY-3493

答案 1 :(得分:1)

请尝试以下操作:

,而不是重写B.metaClass.myMethod
 B.metaClass.invokeMethod = {String methodName, args ->
    println "Catch!"
 }

这个blog post很好地描述了它。

答案 2 :(得分:0)

有一种解决方法,但它只适用于所有类,而不适用于特定实例。

构造前的元类修改:

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()