使用方法引用时的groovy方法范围

时间:2013-02-09 01:00:10

标签: dynamic methods groovy

我有一个groovy类,它查找方法引用然后调用它。被调用的方法是私有方法。当实际的类是子类的一个实例时,它会抛出一个错误,它无法找到私有方法,即使它是父实际调用它的公共方法。

在这种情况下,我显然可以直接调用pMethod2()并且这样可行,但我正在尝试理解为什么这不起作用,如果有办法纠正它,那么它可以工作。< / p>

class Parent {

  def pMethod1() {
    def m = this.&pMethod2
    m() // this call fails if the calling class is of type Child
  }


  private def pMethod2() {}

  public static void main(String[] args) {
    new Child().pMethod1();
  }
}

class Child extends Parent {}

1 个答案:

答案 0 :(得分:4)

有点令人困惑,特别是如果你已经习惯了C / C ++。使用“。&amp;”时得到的结果Groovy中的运算符不是地址,而是MethodClosure的实例。

MethodClosure对象包含所有者和委托对象,在解析要调用的方法时使用该对象。在您的示例中,owner和delegate对象将是“this”,它是Child的一个实例。调用方法只是存储为字符串。

所以,作业

m = this.&pMethod2

只是一种写作的简写方式

m = new MethodClosure(this, "pMethod2")

当你调用m()闭包时,它将尝试通过在所有者和委托对象中分别查找名为“pMethod2”的方法来解析(在运行时)该方法。由于所有者和委托是Child的实例,因此它不会找到位于Parent中的私有方法。

要使您的示例正常工作,您必须确保该方法对闭包的所有者和/或委托人可见。

这可以通过多种方式完成,例如将pMethod2的访问修饰符更改为protected,或者通过使用Parent实例创建闭包;像这样的东西:

m = new Parent().&pMethod2

请注意,在pMethod2实际可见的方法中创建MethodClosure实例是无关紧要的。在一个可见的方法中调用闭包也是无关紧要的。 MethodClosure的所有者或委托人看不到该方法,这是解析方法时使用的方法。