privateフィールドの書き換え
前回のprivateメソッドの呼び出しのついでに、privateフィールドについて、メモ。
こんなクラスがあったとして。(今回cメソッドは面倒だからpublic)
public class A { private String b = "こんにちは。"; public String c(String name) { return name + "さん、" + b; } }
こんなんで実行すると。
public class TestA { public static void main(String[] args) throws Exception { // Aクラスに宣言されているフィールド(フィールド名:b)を取得 java.lang.reflect.Field field = A.class.getDeclaredField("b"); // 取得したprivateフィールドをアクセス可能に変更 field.setAccessible(true); // Aクラスをnew A a = new A(); // 取得したフィールドをnewしたAにて"おはよう。"に変更 field.set(a, "おはよう。"); // newしたAにてcメソッドを実行 System.out.println(a.c("マイケル")); } }
こんな出力結果になる。(ちゃんと「おはよう。」に書き換わっている。)
マイケルさん、おはよう。
というわけだ。
もし、Aクラスのbフィールドが「final」だと、
private final String b = "こんにちは。";
書き換えられずにこんな出力結果になる。
マイケルさん、こんにちは。
じゃ、Aクラスのbフィールドが「static final」だったら?
private static final String b = "こんにちは。";
実行エラーになる。
Exception in thread "main" java.lang.IllegalAccessException: Field is final at sun.reflect.UnsafeQualifiedStaticObjectFieldAccessorImpl.set(UnsafeQualifiedStaticObjectFieldAccessorImpl.java:59) at java.lang.reflect.Field.set(Field.java:656) at TestA.main(TestA.java:15)
じゃ〜、Aクラスのbフィールドが「static」だけだったら?
private static String b = "こんにちは。";
そりゃ当然最初と同じ出力結果になる。(ちゃんと「おはよう。」に書き換わっている。)
マイケルさん、おはよう。
う〜ん・・ま〜・・そ〜か〜・・ く( ´ ⌒ `)ゞ