2013-02-09 58 views
0

我有一個groovy類,它查找方法引用然後調用它。被調用的方法是一種私有方法。當實際的類是子類的一個實例時,它會拋出一個錯誤,即它無法找到私有方法,即使它是父級中的實際調用它的公共方法。使用方法引用時的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 {} 

回答

3

這有點令人困惑,特別是如果你習慣了C/C++。在Groovy中使用「。&」運算符時得到的不是地址,而是MethodClosure的一個實例。

MethodClosure對象包含一個所有者和一個委託對象,當解析要調用的方法時使用該對象。在你的例子中,所有者和委託對象將是「this」,它是Child的一個實例。要調用的方法只是存儲爲一個字符串。

所以,分配

m = this.&pMethod2 

是寫

m = new MethodClosure(this, "pMethod2") 

當你調用M()關閉的只是一個速記方式,它會嘗試解決(在運行時)的方法,通過在所有者和委託對象中分別尋找名爲「pMethod2」的方法。由於所有者和委託是Child的一個實例,因此它不會找到位於Parent中的私有方法。

爲了使您的示例工作,您必須確保方法對閉包的所有者和/或委託可見。

這可以通過多種方式完成,例如通過將pMethod2的訪問修飾符更改爲protected,或者通過使用Parent的實例創建閉包;是這樣的:

m = new Parent().&pMethod2 

注意,是無關緊要,你在pMethod2實際上是可見的方法創建的MethodClosure實例。你在一個可見的方法中調用閉包也是無關緊要的。該方法對MethodClosure的所有者或委託不可見,這是解析方法時使用的方法。