越来越IllegalAccessException从内部类

问题描述:

从父访问受保护的方法时,我有一个非常奇怪的问题和解决怪异:越来越IllegalAccessException从内部类

class Parent { 
    protected void aProtectedMethod() { doSomething(); } 
} 

class Child extends Parent { 
    void anotherMethod() { 
     new SomeInterface() { 
      public void interfaceMethod() { 
       aProtectedMethod(); 
      } 
     }; 
    } 
} 

当child.anotherMethod()运行时,我得到了IllegalAccessException在myProtectedMethod()说我的内部类不能访问父类...

但是,如果我补充一下:

protected void aProtectedMethod() { super.aProtectedMethod(); } 
在我的儿童类

,一切都很好...

我想知道这是为什么?

+1

这是否编译?你确定不是'new SomeInterface {{aProtectedMethod();}}'? – OscarRyz 2010-06-11 18:20:27

+0

OP代码看起来应该可以工作。在new SomeInterface{{ aProtectedMethod();}}中,你有一个方法调用悬而未决的包含方法。 – Curtis 2010-06-11 18:25:48

+0

这只是一个精简的例子。我已经改变了它,使它更加正确,但精神依然存在。 – EnToutCas 2010-06-11 18:27:04

+0

!似乎这是一个已知的问题。 – EnToutCas 2010-06-11 19:59:22

从某种意义上说,这是有道理的。 Parent中的受保护方法可以由Parent访问,也可以是Parent的子类。内部类可以访问其包含的类中的任何内容,其中技术上不是父类中的受保护方法。所以,直到你给Child添加一个受保护的方法,然后才调用Parent的方法。

(嗯,我实际上并不相信我的解释是任何比原来的代码更清晰。对不起。:))

+0

我不知道这个......它归结为范围界定。受保护的方法对子类是可见的,子类中的内部类(当然是非静态的)具有相同的访问权限。 – EnToutCas 2010-06-11 18:29:31

+0

它绝对是范围界定的。但我不确定内部类与父类具有“相同访问权”是否属实。如果是这样,你的原始代码将起作用。如果规则是内部类具有“完全访问其父”,它解释了您所看到的行为 - Parent上的受保护方法可由Child访问,但实际上并不存在IN子。 – Curtis 2010-06-11 18:49:25

+0

我认为GWT延期绑定正在抛弃我。该问题仅在托管模式下发生。当我把它编译成Javascript时,一切都很好。 – EnToutCas 2010-06-11 19:01:01

我不知道我理解你的问题。此代码执行就好了:

interface SomeInterface { 
    public void interfaceMethod(); 
} 

class Parent { 
    private void doSomething() { System.out.println("hello world"); } 
    protected void aProtectedMethod() { doSomething(); } 
} 

class Child extends Parent { 

    public static void main(String... args) { 
     new Child().anotherMethod(); 
    } 

    void anotherMethod() { 
     new SomeInterface() { 
      public void interfaceMethod() { 
       aProtectedMethod();   // line A 
      } 
     }.interfaceMethod(); 
    } 
} 

(打印hello world如预期)

然而,什么可能会混淆大家的是,在A线(见上面的代码),该this参考实际上是指一个实例SomeInterface类型的对象,而不是Child,这可以解释为什么在调用aProtectedMethod时遇到问题。您可以通过编写Child.this访问对Child的引用。


从上IllegalAccessException文档:

一种IllegalAccessException当应用程序试图反射性创建一个实例(比阵列其它)被抛出,设置或获取一个字段,或调用一个方法,但是当前正在执行的方法无法访问指定的类,字段,方法或构造函数的定义。

您是否使用反射API?

+0

现在我想起它,它肯定与反思有关。该错误只发生在GWT托管模式,而不是当我编译到Javascript。 – EnToutCas 2010-06-11 19:03:25

+0

然后我完全不知道发生了什么,为什么。抱歉。 – aioobe 2010-06-11 19:22:23

我试过了,它在普通java(不是GWT编译)中为我工作。

它可能是GWT编译器中的一个bug(或一个功能)。

你可以尝试显式调用的方法是这样的:

Child.this.aProtectedMethod(); 
+0

Child.this.aProtectedMethod()不适合我。但我认为这是GWT延迟绑定和托管模式的问题。我把它编译成Javascript,事情没有问题。确切地说是 – EnToutCas 2010-06-11 19:01:48