2010-05-14 102 views
4

我有一個抽象的Java類MyAbstractClass私有方法。有一個具體的實現MyConcreteClassGroovy調用Java超類的私有方法

public class MyAbstractClass { 
    private void somePrivateMethod(); 
} 

public class MyConcreteClass extends MyAbstractClass { 
     // implementation details 
} 

在我的常規測試類我有

class MyAbstractClassTest { 

    void myTestMethod() { 
     MyAbstractClass mac = new MyConcreteClass() 
     mac.somePrivateMethod() 
    } 
} 

我得到一個錯誤,有對somePrivateMethod沒有這樣的方法簽名。我知道groovy可以調用私有方法,但我猜測問題是私有方法在超類中,而不是MyConcreteClass。有沒有辦法像這樣在超類中調用私有方法(除了使用像PrivateAccessor之類的東西)?

感謝 傑夫

回答

9

,您可以調用私有方法的事實是a bug in the Groovy language,而不是一個功能。但是,我相信這個錯誤是在對封閉方式進行一些更改時故意作爲一種妥協形式引入的。

即使你可以調用私有方法,你也不應該這樣做,因爲希望有一天這個bug會被修復,如果你的程序依賴於調用私有方法,它將被破壞。

如果你真的堅持(ab)使用這種無證行爲,你可以嘗試使用類似ReflectionUtils的東西來調用父類中的私有方法。

另一個解決方法是在父類中調用私有方法的具體類中提供一種方法。例如,下面的代碼「有效」,但它仍然依賴訪問私有成員,這是不好的

class Parent { 
    private foo() {println "foo"} 
} 

class Child extends Parent { 
    public bar() {super.foo()} 
} 

new Child().bar() 
+2

同意100%。私人出於某種原因,私人空間。 – 2010-05-14 15:20:13

+2

我看到你來自哪裏,但是如果你曾經聽過Neal Ford的談話,他實際上稱這是一個功能,而private是java語言的一個特性,而不是java平臺的特性 - 儘管我可以無論如何看。但無論你如何看待它,我認爲這對測試中的有限情況非常有用。我只在需要調用PrivateAccessor(或ReflectionUtils)的地方使用它。在這種特殊情況下,我想執行一個專用的readResolve方法來確保瞬態字段被正確地重新初始化。 – 2010-05-14 15:44:23

+0

我從來沒有聽說過尼爾福特,儘管我非常有興趣聽到他如何證明這一立場。我認爲將其視爲一個功能是不合理的,因爲它被認爲是Groovy JIRA中的一個錯誤,並且在任何地方都沒有提及authorative(Groovy網站,Groovy書籍等),因爲它的預期行爲是私有的。 – 2010-05-14 15:55:36