1

例としてClassFileAssemblersun.reflectパッケージのクラスを考えてみましょう。

このクラスはパッケージ ローカル クラスです。

class ClassFileAssembler implements sun.reflect.ClassFileConstants {...

そのため、名前でさえ使用ClassFileAssemblerできず、直接インポートすることはできません。コンパイル エラーが発生します。

ただしsun.reflect、プロジェクトでという名前のパッケージを作成し、そのClassFileAssembler名前をこのパッケージ内で内部的に使用することはできます。Java コンパイラは、私たちがClassFileAssemblerのパッケージ内にいると認識します。

もしそうなら、なぜクラスオブジェクトへの参照を取得しようとしないのClassFileAssembler.classですか?

Class<ClassFileAssembler> classFileAssemblerClass = ClassFileAssembler.class;

予期せず、このコードは実行時エラーを引き起こします: java.lang.IllegalAccessError: tried to access class sun.reflect.ClassFileAssembler from class sun.reflect.Test.

ClassFileAssemblerただし、クラス オブジェクトを取得することはできます。

Class<ClassFileAssembler> aClass = (Class<ClassFileAssembler>)Class.forName("sun.reflect.ClassFileAssembler");

これは問題なく動作し、完全なクラスの説明が得られます。


したがって、質問は次のとおりです。

1) テクニックの違いは何ですか?Class.forName0クラスオブジェクトへの参照を取得する方法とその方法.classは?

2) なぜこのようにセキュリティチェックが異なるのですか?

.class3)参照をそのように保護する理由は何ですか?

4) これらの手法は異なるクラスローダーを使用していますか?

4

3 に答える 3

3

Class.forName は、クラスがパッケージ ローカルかどうかを気にしません。アクセスがチェックされるのは、そのクラスを使用しようとするときです。ところで、setAccessible(true) を実行すると、これらのアクセス制限を回避できます。

Reflection ライブラリを使用すると、Java コードでは実行できない多くのことを実行できます。Javaには、できることとできないことに関するルールがあります。finalたとえば、コンストラクターの外側または複数回フィールドを設定することはできません。注: JVM にはこの制限がなく、実行時にリフレクションを使用して変更できます。

このクラスがパッケージ ローカルである理由は、このパッケージ外のコードへのクラスのアクセスを制限するためです。これは、実際にアクセスしようとしてもアクセスできないという意味ではありませんが、真剣に考えずにアクセスする可能性は低いです。たとえば、IDE にクラスをインポートすると、com.sun.* からのクラスが提案されることがよくありますが、これは正しい選択ではありません。(マイ IDE はこれらを無視するように設定できますが、不要な新しいパッケージを見つけたように見えることがよくあります)

リフレクションがこれを実行できる理由は、シリアライゼーションなどの機能をサポートするためです。シリアル化では、シリアル化ライブラリのパッケージの外部でクラスをシリアル化し、フィールドを取得して、逆シリアル化するときにそれらをリセットできる必要があります。Reflections は、多くの Inversion of Control ライブラリでも使用されていますが、これは設計時に念頭に置いていたものではないと思われます。

于 2013-01-25T09:20:19.663 に答える
2

のjavadocClass#forNameを確認すると、次のことがわかります。

このメソッドは、要求されたクラスがその呼び出し元にアクセスできるかどうかをチェックしないことに注意してください。

于 2013-01-25T09:19:57.840 に答える
0
  1. 違いはありません。.classただし、パッケージのプライベート (修飾子なし) クラスの static フィールドにはアクセスできませんClassFileAssembler
  2. 誰でも Class インスタンスにアクセスできますが、フィールドは保護されています。
  3. 実際、この方法で参照を保護するように設計された人は誰もいません.class。これは、他のフィールドを保護することの副作用です。
  4. 私はそうは思わない。
于 2013-01-25T09:28:44.797 に答える