1. ホーム
  2. java

[解決済み] Java リフレクション - setAccessible(true)の影響

2022-09-08 06:59:45

質問

クラス内のフィールドの値を動的に設定するために、いくつかのアノテーションを使用しています。私はそれが公開、保護、またはプライベートであるかに関係なくこれを行いたいので、私は setAccessible(true) を呼び出す前に毎回フィールドオブジェクト上で set() メソッドを呼び出します。私の疑問は setAccessible() の呼び出しは、フィールド自体にどのような影響を与えるのでしょうか?

より具体的には、それがプライベートなフィールドであり、この一連のコード呼び出しが setAccessible(true) . もし、コードの中の他の場所がリフレクションによって同じフィールドを取り出すとしたら、そのフィールドはすでにアクセス可能なのでしょうか?それとも getDeclaredFields()getDeclaredField() メソッドは毎回Fieldオブジェクトの新しいインスタンスを返しますか?

質問を述べる別の方法は、もし私が setAccessible(true) を呼び出した場合、終了後に元の値に戻すことがどれほど重要なのでしょうか?

どのように解決するのですか?

とは setAccessible() の挙動を変更します。 AccessibleObject の挙動を変更する、つまり Field のインスタンスであり、クラスの実際のフィールドではありません。ここでは のドキュメントです。 (抜粋) を参照してください。

の値は true は、反映されたオブジェクトが使用される際に、Java言語のアクセス制御のチェックを抑制することを示します。

そして実行可能な例です。

public class FieldAccessible {
    public static class MyClass {
        private String theField;
    }

    public static void main(String[] args) throws Exception {
        MyClass myClass = new MyClass();
        Field field1 = myClass.getClass().getDeclaredField("theField");
        field1.setAccessible(true);
        System.out.println(field1.get(myClass)); // no exception
        Field field2 = myClass.getClass().getDeclaredField("theField");
        System.out.println(field2.get(myClass)); // IllegalAccessException
    }

}