1

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

在这种情况下,我显然可以pMethod2()直接调用并且它有效,但我试图理解为什么这不能像书面那样工作,以及是否有办法纠正它以便它工作。

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 {}
4

1 回答 1

5

这有点令人困惑,尤其是如果您习惯于 C/C++。在 Groovy 中使用“.&”运算符时得到的不是地址,而是 MethodClosure 的实例。

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

所以,任务

m = this.&pMethod2

只是一种简写方式

m = new MethodClosure(this, "pMethod2")

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

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

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

m = new Parent().&pMethod2

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

于 2013-02-09T20:39:38.190 回答