まずコードの一部を見てみましょう:
public class Main{ public static void main(String[] args){ Integer num1 = 100; Integer num2 = 100; Integer num3 = 200; Integer num4 = 200; '''//输出结果''' System.out.println(num1==num2); System.out.println(num3==num4); } }
結果はどうなるかわかりますか?
多くの人は結果が全て正しいと思うでしょうが、結果はこんなものではありません
true
false
なぜこの結果になるのでしょうか?結果をメモリの観点から説明すると、num1 と num2 は同じオブジェクトを指しますが、num3 と num4 は異なるオブジェクトを指します。次に、その理由を説明します。Integer 型の valueof メソッドのソース コードを見てみましょう:
public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; return new Integer(i); }
IntegerCache の実装:
これらからわかるように、 valueof メソッドが Integer 型オブジェクトを作成する場合、値の範囲は [-128,127] です。この範囲内では、値がこの範囲を超えると、ポインタは IntegerCache.cache 内の既存のオブジェクト参照を指します。オブジェクトが作成されます。
注意すべき点は、すべての型がこの範囲内にあるわけではないということです。Double 型を見てください:
最終的な出力結果:
false
Integer、Short、Byte、Character、および Long クラスの valueOf メソッドの実装は似ていることに注意してください。
'''// IntegerCache,一个内部类,注意它的属性都是定义为static final''' private static class IntegerCache { static final int high; '''//缓存上界,暂为null''' static final Integer cache[]; '''//缓存的整型数组''' '''// 块,为什么定义为块''' static { final int low = -128; '''// 缓存下界,不可变了。只有上界可以改变''' '''// high value may be configured by property''' '''// h值,可以通过设置jdk的AutoBoxCacheMax参数调整(以下有解释),自动缓存区间设置为[-128,N]。注意区间的下界是固定''' int h = 127; if (integerCacheHighPropValue != null) { '''// Use Long.decode here to avoid invoking methods that''' '''// require Integer's autoboxing cache to be initialized''' // 通过解码integerCacheHighPropValue,而得到一个候选的上界值''' int i = Long.decode(integerCacheHighPropValue).intValue(); '''// 取较大的作为上界,但又不能大于Integer的边界MAX_VALUE''' i = Math.max(i, 127); '''// Maximum array size is Integer.MAX_VALUE''' h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; '''//上界确定''' '''// 就可以创建缓存块,注意缓存数组大小''' cache = new Integer[(high - low) + 1]; // int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); '''// -128到high值逐一分配到缓存数组''' } private IntegerCache() {} }
public class Main{ public static void main(String[] args){ Double i1 = 100.0; Double i2 = 100.0; Double i3 = 200.0; Double i4 = 200.0; System.out.println(i1==i2); System.out.println(i3==i4); } }
Java のアンボックス化の詳細な分析に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。