Groovy 元编程 (getProperty) 仅在从 class 外部调用时才有效?

Groovy metaprogramming (getProperty) only works when called from outside the class?

我用 Groovy 尝试了一些(运行时)元编程。我继续实施 GroovyInterceptable 的 getProperty 方法。但是现在我发现这只有在从外部获取对象上的 属性 时才有效。当从 class 的方法内部获取 属性 时,我的 getProperty 方法没有被调用(参见下面的代码示例)。

现在,这是意料之中的吗?一直都是这样吗?一位同事告诉我,这在过去曾经有所不同(与他记忆中的不同)。是否有另一种方式 属性 从内部和外部读取都会调用我的 getProperty 方法?

class SomeGroovyClass implements GroovyInterceptable {  

  def foo

  SomeGroovyClass() {
    foo = "ctor"
  }

  def getProperty(String name) {     
    if (name == "foo") {
      return "blub"
    } else {
      return "foo"
    }
  }

  def test2() {
    System.out.println "foo from inside via method call: " + this.foo
  }
}

def someGroovyClass = new SomeGroovyClass() 
System.out.println "foo from outside: " + someGroovyClass.foo
someGroovyClass.test2()

输出是

  foo from outside: blub
  foo from inside via method call: ctor

强制使用 getProperty 方法的一种方法是强制使用用于访问的类型 this。将您的 test2 方法更改为:

  def test2() {
    println "foo from inside via method call: " + ((GroovyInterceptable) this).foo
  }

结果:

~> groovy solution.groovy
foo from outside: blub
foo from inside via method call: blub

强制类型的替代方法:

  def test2() {
    def me = this as GroovyInterceptable
    println "foo from inside via method call: " + me.foo
  }

  def test2() {
    GroovyInterceptable me = this
    println "foo from inside via method call: " + me.foo
  }

我可以理解 groovy 编译器的来源...它真的没有办法知道你正在寻找 foo 属性 的哪种处理方式,除非你很明确。

我相信 getProperty 机制的主要目的是覆盖对 non-existent 属性的访问。这使得默认使用现有的 属性 在我看来是一个合理的选择,并且他们仍然敞开大门,因为您总是可以像上面那样使用类型化访问来强制执行。