IllegalAccessError:访问受保护的方法

我有两节课。

A类有保护方法m()aA的实例。

B类与A类在同一个包装中。

我试图访问am()但我得到IllegalAccessError

怎么了?

编译器应该捕获这样的错误。 正如你在运行时显然得到的那样,发生了一些奇怪的事情。 您可能已更改源代码但已完全重新编译。

另一个潜在但又模糊的问题是通过不同的类加载器加载类。 即使包名称相同,从不同类加载器加载的类也将位于不同的包中(与由不同类加载器加载的具有相同名称的类相同的方式将是不同的类)。

如果类A和B由不同的类加载器加载,则会发生这种情况。 然后,jvm将这些类视为不同的“运行时包”。 引用jvm规范 ,第5.3节:

在运行时,类或接口不是由其名称单独确定,而是由一对确定:它的完全限定名称及其定义的类加载器。 每个这样的类或接口都属于单个运行时包。 类或接口的运行时包由包名称和类或接口的类加载器定义。

在5.4.4节中:

当且仅当满足以下任一条件时,才能访问类或接口D的字段或方法R.

R既可以是受保护的,也可以是包私有的(即既不公开也不受保护也不是私有),并且由与D相同的运行时包中的类声明。

它必须工作,请参阅以下示例,该工作正常:

 package com.stackoverflow; public class TEST { static class A { protected void m() { System.out.println("hello from Am()"); } } static class B { public B() { am(); } private A a = new A(); } /** * @param args */ public static void main(String[] args) { B b = new B(); } } 

打印出预定的消息:“ hello from Am()

“protected修饰符指定只能在自己的包中访问该成员(与package-private一样),此外,还可以在另一个包中通过其类的子类访问。”

请参阅控制对类成员的访问 。

编译器应该捕获这样的错误。 当你在运行时得到它时,发生了一些错误。 很可能你已经改变了完全重新编译的源代码。

它必须工作。 这是一个运行的例子 –

**

  • 一级A.

**

 package com.test; public class A { protected void m(){ System.out.println("Hi Stackoverflow"); } } 

**

  • CLASS B.

**

 package com.test; public class B{ public static void main(String[] args) { A a = new A(); am(); } } 

打印预期的字符串

您好Stackoverflow