【问题标题】:Access a property inside invokeMethod() implemented in a trait访问在 trait 中实现的 invokeMethod() 中的属性
【发布时间】: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 如果您可以使其与示例代码中所示的特征结合使用,当然可以。 :-)

标签: groovy metaprogramming


【解决方案1】:

事实证明,直接字段访问不需要使用@

trait Bar implements GroovyInterceptable {
    def bar = "bar"

    @Override
    invokeMethod(String name, Object args) {
        System.out.println(Bar__bar)
        metaClass.getMetaMethod(name, args).invoke(this, args)
    }

    def doSomething() {
    }
}

class Foo implements Bar {
}

def foo = new Foo()
foo.doSomething()

【讨论】:

  • 这看起来是正确的,我得到了这个异常:MissingPropertyException: No such property: Bar__bar for class: de.appplant.workshop.data.Foo
  • 奇怪。在我的机器上运行正常。
  • 是的,根据documentation 它有效。我正在使用带有 Groovy 2.4.3 的 Android Studio。
  • 代码在作为脚本执行时运行良好。当特征在其自己的文件中声明时,它会失败并出现上述异常。 :-/
  • 老实说,我只是尝试了 thisBar@._ 的所有可能组合,并希望代码完成能给我一些提示。 :-D
猜你喜欢
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
  • 2015-06-20
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
相关资源
最近更新 更多