java.lang.IllegalAccessError:尝试从类Entity访问字段ConcreteEntity.instance
好的,这是交易。我正在尝试访问ConcreteEntity.instance
,这是默认ClassLoader
内存在访问类型默认的字段,Entity.getInstance
是子ClassLoader
中存在的方法。
现在请记住,它们都在同一个包中,但是IllegalAccessError
被抛出。是否有解决此问题的方法,并不涉及我实际将实体类加载到与ClassLoader
相同的ConcreteEntity
内?
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 at检索的字节码是“编译后”生成的异常。
感谢Gamb清理帖子。
答案 0 :(得分:28)
请参阅my answer至a similar question,除非您的情况很明显,您正在处理多个类加载器:
jvm认为从不同的类加载器加载的类在不同的运行时包&#34;中,即使它们具有相同的包名。引自the jvm spceification,第5.3节:
在运行时,类或接口不仅由其名称决定,而是由一对确定:它的完全限定名称及其定义的类加载器。每个这样的类或接口都属于一个运行时包。类或接口的运行时包由包名称和类或接口的类加载器确定。
在第5.4.4节中:
当且仅当满足以下任一条件时,才能访问类或接口D的字段或方法R:
...
R受保护或包私有(即既不公开也不保护也不私有),并且由与
相同的运行时包中的类声明。
答案 1 :(得分:1)
Javadoc:通常,编译器会捕获此错误;如果类的定义发生了不兼容的更改,则此错误只能在运行时发生。
由于我认为尝试了一些困难的类操作,也许是类加载,在两个类的加载方式上投入一些时间。 (在极少数情况下,显式的serialVersionId可能有所帮助。)
如果类是相关的(超级/子类),则尝试使用接口删除该关系。可能使用注射。 那不是两次引用/加载一个类。
抱歉,我不能给出具体的答案。