読者です 読者をやめる 読者になる 読者になる

プリミティブのラッパーのコンストラクタの代わりに valueOf を使う件

Java

valueOfインスタンスを取得することになるわけか。

というわけで、Integer#valueOf(int) を見てみます。(これは Java 8 ですが)

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

そういえばどこかで「valueOf メソッドはキャッシュしているインスタンスを返す」という情報を読んだことがあったような気がする。デフォルトでは [-128, 127] の範囲の値をキャッシュするようです。(-XX:AutoBoxCacheMax オプションで変更可能)

以下、簡単にですが試してみます。

当然、以下は false になります。

Integer constructor = new Integer(100);
Integer valueOf = Integer.valueOf(100);
assertThat((constructor == valueOf), is(false));

以下はキャッシュの範囲内なので、同一のインスタンスが返ります。よって true になります。

Integer valueOf1 = Integer.valueOf(100);
Integer valueOf2 = Integer.valueOf(100);
assertThat((valueOf1 == valueOf2), is(true));

以下も同様。

Integer valueOf1 = Integer.valueOf(127);
Integer valueOf2 = Integer.valueOf(127);
assertThat((valueOf1 == valueOf2), is(true));

以下も同様。

Integer valueOf1 = Integer.valueOf(-128);
Integer valueOf2 = Integer.valueOf(-128);
assertThat((valueOf1 == valueOf2), is(true));

以下はキャッシュの範囲外なので、新しくインスタンスを生成して返します。よって false になります。

Integer valueOf1 = Integer.valueOf(128);
Integer valueOf2 = Integer.valueOf(128);
assertThat((valueOf1 == valueOf2), is(false));

以下も同様。

Integer valueOf1 = Integer.valueOf(-129);
Integer valueOf2 = Integer.valueOf(-129);
assertThat((valueOf1 == valueOf2), is(false));

なるほど。