我有一个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 {}
答案 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的所有者或委托人看不到该方法,这是解析方法时使用的方法。