14

java.lang.IllegalAccessError:试图从类 Entity 访问字段 ConcreteEntity.instance

好的,这就是交易。我正在尝试访问ConcreteEntity.instancewhich 是一个具有访问类型 default 的字段,该字段存在于 default 中ClassLoader,并且Entity.getInstance是一个存在于 child 中的方法ClassLoader

现在请记住,它们都在同一个包中,但是IllegalAccessError正在抛出一个。这个问题有没有解决方案,不涉及我实际加载 EntityClassLoaderConcreteEntity

0 new #14 <Entity>
 3 dup
 4 aload_0
 5 invokevirtual #18 <Adapter.getInstance>
 8 checkcast #20 <sl>
11 getfield #24 <sl.d>
14 invokespecial #25 <Entity.<init>>
17 areturn

通过 jclasslib 检索到的字节码是在“编译后”生成的异常。

感谢 Gamb 清理帖子。

4

2 回答 2

31

请参阅类似问题的回答,除非您的情况很明显您正在处理多个类加载器:

jvm 认为从不同类加载器加载的类位于不同的“运行时包”中,即使它们具有相同的包名。引用jvm spceification,第 5.3 节:

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

在第 5.4.4 节中:

当且仅当以下任一条件为真时,类或接口 D 才能访问字段或方法 R:

...

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

于 2012-12-28T14:21:33.807 回答
1

Javadoc:通常,这个错误会被编译器捕获;如果类的定义发生了不兼容的更改,则此错误只会在运行时发生。

因为我认为尝试了一些困难的类操作,也许是类加载,所以在两个类的加载方式上投入了一些时间。(在极少数情况下,显式的 serialVersionId 可能会有所帮助。)

如果类是相关的(超类/子类),则尝试使用接口删除该关系。可能使用注射。那不是两次引用/加载一个类。

抱歉,我无法给出具体答案。

于 2012-12-28T13:55:04.307 回答