2010-05-14 76 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