14

java.lang.IllegalAccessError:クラスEntityからフィールドConcreteEntity.instanceにアクセスしようとしました

さて、これが取引です。ConcreteEntity.instanceデフォルト内に存在するアクセスタイプdefaultのフィールドでありClassLoaderEntity.getInstance子に存在するメソッドであるにアクセスしようとしていますClassLoader

これらは両方とも同じパッケージに含まれていることに注意してください。ただし、IllegalAccessErrorがスローされます。ClassLoaderと同じ内部にEntityクラスを実際にロードする必要のないこの問題の解決策はあり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を介して取得されたバイトコードは、「コンパイル後」に生成されます。

投稿をクリーンアップしてくれたGambに感謝します。

4

2 に答える 2

31

複数のクラスローダーを扱っていることが明らかな場合を除いて、同様の質問に対する私の回答を参照してください。

jvmは、異なるクラスローダーからロードされたクラスが、同じパッケージ名であっても、異なる「ランタイムパッケージ」にあると見なします。jvm spceification、セクション5.3からの引用:

実行時に、クラスまたはインターフェースは、その名前だけでなく、完全修飾名とその定義クラスローダーのペアによって決定されます。このような各クラスまたはインターフェースは、単一のランタイムパッケージに属します。クラスまたはインターフェイスのランタイムパッケージは、パッケージ名とクラスまたはインターフェイスの定義クラスローダーによって決定されます。

そしてセクション5.4.4で:

フィールドまたはメソッドRは、次の条件のいずれかが当てはまる場合にのみ、クラスまたはインターフェイスDにアクセスできます。

..。

Rは保護されているかパッケージプライベート(つまり、パブリックでも保護でもプライベートでもない)であり、Dと同じランタイムパッケージのクラスによって宣言されます。

于 2012-12-28T14:21:33.807 に答える
1

Javadoc:通常、このエラーはコンパイラによってキャッチされます。このエラーは、クラスの定義が互換性なく変更された場合にのみ実行時に発生する可能性があります。

難しいクラス操作、おそらくクラスのロードが試みられていると思うので、両方のクラスがどのようにロードされるかに時間を費やしてください。(まれに、明示的なserialVersionIdが役立つ場合があります。)

クラスが関連している場合(スーパー/サブクラス)、インターフェースを使用してその関係を削除してみてください。おそらくインジェクションを使用します。これは、クラスを2回参照/ロードすることではありません。

申し訳ありませんが、具体的な答えは出せません。

于 2012-12-28T13:55:04.307 に答える