続・finalフィールドへの参照
前回は単なる文字列のfinalフィールドの参照だった。
今回は、参照先のfinalフィールドがメソッドを呼び出していた場合を
チェックしてみる。
まず、Mainクラス。
次にMainから参照されるAクラス。
public class Main {
public static void main(String args[]) {
System.out.println("A-AAA : " + A.AAA);
}
}
finalフィールドは、Bクラスのメソッドをコールしている。
そして、Bクラス
public class A {
public static final String AAA = B.getBBB();
}
public class B {
public static final String BBB = "bbb";
public static String getBBB() {
return BBB;
}
}
Mainを普通に実行した結果。
普通に表示される。
> java Main
A-AAA : bbb
次に、BのfinalフィールドBBBを"final"に変えて、
BのみコンパイルしてMainを実行する。
というわけで、Bを変えるとMainも変わっている。
> java Main
A-AAA : final
まぁ、メソッド呼び出ししている
=実行時じゃないとどんな値が返ってくるかわからん。
=コンパイラは置き換えない
という、当たり前の結果に(汗
一応、Mainを逆コンパイルした結果。
前回同様、Jadを使用。
public class Main { public Main() { } public static void main(String args[]) { System.out.println( (new StringBuilder()).append("A-AAA : ").append(A.AAA).toString()); } }
文字列の連結がStringBuilderに置き換わってる〜!
というびっくり感はさておき、前回とは違って
きちんとA.AAAを参照するという実装のままになっている。
# いつのまにか、JDK1.5を使っていたということは秘密だ。
というわけで、finalフィールドの参照で、そのfinalフィールドが
メソッド呼び出しとかしてなくて単なる文字列の場合に
置き換わるってことで。
当然の結果だが、まぎらわしい。