続・finalフィールドへの参照

前回は単なる文字列のfinalフィールドの参照だった。
今回は、参照先のfinalフィールドがメソッドを呼び出していた場合を
チェックしてみる。


まず、Mainクラス。


public class Main {
public static void main(String args[]) {
System.out.println("A-AAA : " + A.AAA);
}
}
次にMainから参照されるAクラス。
finalフィールドは、Bクラスのメソッドをコールしている。

public class A {
public static final String AAA = B.getBBB();
}
そして、Bクラス

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を実行する。

> java Main
A-AAA : final
というわけで、Bを変えるとMainも変わっている。
まぁ、メソッド呼び出ししている
=実行時じゃないとどんな値が返ってくるかわからん。
コンパイラは置き換えない
という、当たり前の結果に(汗


一応、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フィールドが
メソッド呼び出しとかしてなくて単なる文字列の場合に
置き換わるってことで。
当然の結果だが、まぎらわしい。