越来越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(); }
在我的儿童类
,一切都很好...
我想知道这是为什么?
从某种意义上说,这是有道理的。 Parent中的受保护方法可以由Parent访问,也可以是Parent的子类。内部类可以访问其包含的类中的任何内容,其中技术上不是父类中的受保护方法。所以,直到你给Child添加一个受保护的方法,然后才调用Parent的方法。
(嗯,我实际上并不相信我的解释是任何比原来的代码更清晰。对不起。:))
我不知道这个......它归结为范围界定。受保护的方法对子类是可见的,子类中的内部类(当然是非静态的)具有相同的访问权限。 – EnToutCas 2010-06-11 18:29:31
它绝对是范围界定的。但我不确定内部类与父类具有“相同访问权”是否属实。如果是这样,你的原始代码将起作用。如果规则是内部类具有“完全访问其父”,它解释了您所看到的行为 - Parent上的受保护方法可由Child访问,但实际上并不存在IN子。 – Curtis 2010-06-11 18:49:25
我认为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?
我试过了,它在普通java(不是GWT编译)中为我工作。
它可能是GWT编译器中的一个bug(或一个功能)。
你可以尝试显式调用的方法是这样的:
Child.this.aProtectedMethod();
Child.this.aProtectedMethod()不适合我。但我认为这是GWT延迟绑定和托管模式的问题。我把它编译成Javascript,事情没有问题。确切地说是 – EnToutCas 2010-06-11 19:01:48
这是否编译?你确定不是'new SomeInterface {{aProtectedMethod();}}'? – OscarRyz 2010-06-11 18:20:27
OP代码看起来应该可以工作。在
new SomeInterface{{ aProtectedMethod();}}
中,你有一个方法调用悬而未决的包含方法。 – Curtis 2010-06-11 18:25:48这只是一个精简的例子。我已经改变了它,使它更加正确,但精神依然存在。 – EnToutCas 2010-06-11 18:27:04