【发布时间】:2015-04-17 09:45:41
【问题描述】:
以下 Groovy trait 实现了 GroovyInterceptable 接口,以允许在方法调用之前和之后执行代码。
trait Bar implements GroovyInterceptable {
def bar = "bar"
@Override
invokeMethod(String name, Object args) {
System.out.println(bar)
metaClass.getMetaMethod(name, args).invoke(this, args)
}
def doSomething() {
}
}
以下类实现了特征Bar。
class Foo implements Bar {
}
看看下面的代码。
def foo = new Foo()
foo.doSomething()
对doSomething() 的调用被invokeMethod() 拦截。发生java.lang.StackOverflowError 是因为访问invokeMethod() 内的属性bar 隐式调用了bar 的getter,而invokeMethod() 又试图再次访问bar。
如何在不调用该属性的 getter 或 setter 的情况下访问 invokeMethod 内的类属性?
结合使用 this.@bar 访问属性的 trait 不起作用。
调用被拦截方法的代码metaClass.getMetaMethod(name, args).invoke(this, args) 可能不正确,尽管它在直接在类中使用特征逻辑时有效。
编辑解决方案:
用户Opal 提供的已接受答案就像脚本环境中的魅力一样。由于 trait 是一个更大项目的一部分并在它自己的文件中定义,我让它像这样工作:
package com.example.project
trait Bar implements GroovyInterceptable {
def bar = "bar"
@Override
invokeMethod(String name, Object args) {
System.out.println(this.com_example_project_Bar__bar)
metaClass.getMetaMethod(name, args).invoke(this, args)
}
def doSomething() {
}
}
【问题讨论】:
-
试试
this.@bar?使用 2.4.0 它可以正常工作。 -
@Opal 感谢您的快速回复。是的,它适用于
this.@bar。我认为示例不完整,我的问题稍微复杂一些,所以我编辑了示例代码。 -
我可以将其添加为被接受的答案吗?
-
@Opal 如果您可以使其与示例代码中所示的特征结合使用,当然可以。 :-)