文字列な定数クラスでjava.lang.String.String(java.lang.String)が初めて必要になったよ。
以下、「"hoge"」と「new String("hoge")」の動作例ですよ。
Constant.java。定数クラス。
//Constant.java package aaaa; public class Constant { /* いつもの */ static final String NORMAL = "normal"; /* 明示的に別の実態を作成 */ static final String ABNORMAL = new String("normal"); }
Main.java。定数を標準出力に出力するだけ。
//Main.java package aaaa; public class Main { public static void main(String[] args) { /* いつもの */ System.out.println("NORMAL = " + Constant.NORMAL); /* 明示的に別の実態を作成 */ System.out.println("ABNORMAL = " + Constant.ABNORMAL); } }
コンパイル→実行。
C:?temp>javac aaaa/Main.java C:?temp>javac aaaa/Constant.java C:?temp>java aaaa/Main NORMAL = normal ABNORMAL = normal
ここまでは問題ないよね。
ここで、Constant.javaを書き換える。("normal"→"abnormal")
//Constant.java package aaaa; public class Constant { /* いつもの */ static final String NORMAL = "abnormal"; /* 明示的に別の実態を作成 */ static final String ABNORMAL = new String("abnormal"); }
Constant.javaをコンパイル→実行すると…
C:?temp>javac aaaa/Constant.java C:?temp>java aaaa/Main NORMAL = normal ABNORMAL = abnormal
…「いつもの」が変更されてない!!
このときMain.javaをjadでデコンパイルすると…
// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov. // Jad home page: http://www.kpdus.com/jad.html // Decompiler options: packimports(3) ansi // Source File Name: Main.java package aaaa; import java.io.PrintStream; // Referenced classes of package aaaa: // Constant public class Main { public Main() { } public static void main(String args[]) { System.out.println("NORMAL = normal"); System.out.println("ABNORMAL = " + Constant.ABNORMAL); } }
…なるほど。「いつもの」の書き方だと、コンパイル時点でクラスファイルに定数が埋め込まれるのでした。
Main.javaもコンパイル→実行すると…
C:?temp>javac aaaa/Main.java C:?temp>java aaaa/Main NORMAL = abnormal ABNORMAL = abnormal
…これが期待する動作でした。
このときMain.javaをjadでデコンパイルすると…
// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov. // Jad home page: http://www.kpdus.com/jad.html // Decompiler options: packimports(3) ansi // Source File Name: Main.java package aaaa; import java.io.PrintStream; // Referenced classes of package aaaa: // Constant public class Main { public Main() { } public static void main(String args[]) { System.out.println("NORMAL = abnormal"); System.out.println("ABNORMAL = " + Constant.ABNORMAL); } }
- 結論
- 定数クラスの定数を変更するとき、「"hoge"」だと定数クラスを使用しているクラスも再コンパイルが必要だ
- 定数クラスの定数を変更するとき、「new String("hoge")」だと定数クラスを再コンパイルするだけで良いよ
- 補足
- 既に「"hoge"」となっている場合、そこを「new String("hoge")」に変更するだけではダメですよ(定数クラスを使用しているクラスも再コンパイルが必要)
…以上。
っていうか、
- EclipseならConstant.javaを書き換えて実行すると、自動でMain.javaもコンパイルしてくれる
から、こんなことは普段意識する必要なし。これを意識する必要があるのは…ノーコメント。