看板に偽り

先日に続いてJavaの話であることを断っておきます。
JavaのIntegerクラスが、どういうわけかIntegerCacheとかいうprivate staticなクラスを使っていることを書きました。で、IntegerのvalueOf(int i)というメソッドの説明を読むと、確かに

指定した int 値を表す Integer インスタンスを返します。新規 Integer インスタンスが不要な場合、通常このメソッドがコンストラクタ Integer(int) に優先して使用されます。その理由は、このメソッドが頻繁に要求される値をキャッシュするので、操作に必要な領域や時間がはるかに少なくて済む場合が多いためです。

と書いてあります。なるほど、キャッシュしてあることはきちんとドキュメントに書いてあるというわけですね。まあ、ぶっちゃけそのIntegerCacheクラスというのは、

private static class IntegerCache {
  private IntegerCache(){}
    static final Integer cache[] = new Integer[-(-128) + 127 + 1];
    static {
      for(int i = 0; i < cache.length; i++)
        cache[i] = new Integer(i - 128);
      }
    }
}

というもので、正直クラスにする意味がよくわからないんですけれども。
で、その他のNumber関係のクラスにはどういうキャッシュがあるのか調べてみました。結果だけ書きますと、

Integer -128 <= x <= 127
Long -128 <= x <= 127
Short -128 <= x <= 127
Byte -128 <= x <= 127
Character x <= 127
Double
Float

という感じで、Characterだけはちょっと定義範囲が違う感じ。まあ、後半のCharacterなんてCharとしては誰も使わないだろうから正しいんでしょう。
問題は、DoubleとFloatです。なぜだかキャッシュされていません。もちろん、キャッシュするのが難しいというのはあるでしょう。でもせめて0と1くらいは・・・と思わずに入られません。何が問題かというと、Doubleの仕様Floatの仕様にキャッシュしていると書いている点です。ところが、実際にソースを見てみると、

public static Double valueOf(double d) {
  return new Double(d);
}

えっと・・・早いどころか逆にvalueOfによって遅くなってます。まあ、無視できる範囲の遅さでしょうけれど。