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 = "こんにちは。";

そりゃ当然最初と同じ出力結果になる。(ちゃんと「おはよう。」に書き換わっている。)

マイケルさん、おはよう。


う〜ん・・ま〜・・そ〜か〜・・ く( ´ ⌒ `)ゞ