HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

無駄むだムダァー

超極小爆弾だけど(メモリに対する)‥

return new String("0");

‥よっぽど特殊な事情がない限り、"0"っていう文字列を表す別のインスタンスなんて必要ないと思うんだけど。例えば、java.util.IdentityHashMapを使わなければいけないケースとか。
ちなみに、実験用のコード断片以外でIdentityHashMapを使ったことは、ない。

ただ、「new String("0")」みたいなことを絶対やらないかというと、そういうわけではなくて、次のようなケースはありうる。

public final class Constants {
    // (1) リテラルの代入による初期化
    public static final String CONST_1 = "111";
    // (2) newしたオブジェクト(の参照)を代入するという初期化
    public static final String CONST_2 = new String("222");
    // (3) メソッドの戻り値を代入するという初期化
    public static final String CONST_3 = "333".intern();
}

public class Hoge {
    public static void hoge1() {
        System.out.println("    hoge1: " + Constants.CONST_1);
    }
    public static void hoge2() {
        System.out.println("    hoge2: " + Constants.CONST_2);
    }
    public static void hoge3() {
        System.out.println("    hoge3: " + Constants.CONST_3);
    }
    public static void main(String[] args) {
        hoge1();
        hoge2();
        hoge3();
    }
}

これに対して、次の順で作業していくと‥

shell> javac Constants.java
shell> javac Hoge.java
shell> java Hoge
    hoge1: 111
    hoge2: 222
    hoge3: 333
# Constants.javaの"111"、"222"、"333"を、
#   それぞれ"one"、"two"、"three"に書き換える。
shell> javac Constants.java
shell> java Hoge
    hoge1: 111
    hoge2: two
    hoge3: three

ということが起こる。これは、static finalで、宣言と代入が同時に行われていて、代入される値がリテラルであるようなフィールドに対する参照は、コンパイル時にリテラルに置き換えられてしまうため。(SunのJDK 1.5.0_11で確認。)
ただ、この理由にしても、私自身は(2)の方法だけは使わないけど。オブジェクトひとつ無駄に生成されるし、static finalなのでそのオブジェクトをずっと保持しておくことになるわけだし。


このようなコードを書いたのは誰だろう、と思って調べてみたら、やっぱりあなた(誰)でしたか。