JAVA自動裝箱拆箱以及裝箱時的快取問題
阿新 • • 發佈:2018-12-18
概述
JAVA中的自動裝箱指的是把基本型別的值轉換為對應的包裝類物件,自動拆箱則相反。
JAVA中的基本型別: boolean/1, byte/8, char/16, short/16, int/32, long/64,float/32, double/64
基本型別都有對應的包裝型別
對應的包裝型別: Boolean, Byte, Character, Short, Integer, Long, Float, Double
基本型別與其對應的包裝型別之間的賦值使用自動裝箱與拆箱完成
Integer x = 2; // 裝箱
int y = x; // 拆箱
自動裝箱時呼叫包裝類的valueOf
自動拆箱時呼叫包裝類的xxxValue方法,比如intObj.intValue();
注意,自動裝箱拆箱是編譯器幫我們自動轉換的,我們不需要手工呼叫valueOf()和intValue()方法。
快取池
new Integer(123) 與 Integer.valueOf(123) 的區別在於:
- new Integer(123) 每次都會新建一個物件;
- Integer.valueOf(123) 會使用快取池中的物件,多次呼叫會取得同一個物件的引用。
Integer x = new Integer(123); Integer y = new Integer(123); System.out.println(x == y); // false Integer z = Integer.valueOf(123); Integer k = Integer.valueOf(123); System.out.println(z == k); // true
valueOf() 方法的實現比較簡單,就是先判斷值是否在快取池中,如果在的話就直接返回快取池的內容。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
在 Java 8 中,Integer 快取池的大小預設為 -128~127。
static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; }
我們可以通過-Djava.lang.Integer.IntegerCache.high=10000來設定快取的範圍
編譯器會在自動裝箱過程呼叫 valueOf() 方法,因此多個 Integer 例項使用自動裝箱來建立並且值相同,那麼就會引用相同的物件。
Integer m = 123;
Integer n = 123;
System.out.println(m == n); // true
基本型別對應的緩衝池如下:
- boolean values true and false
- all byte values
- short values between -128 and 127
- int values between -128 and 127
- char in the range \u0000 to \u007F
在使用這些基本型別對應的包裝型別時,就可以直接使用緩衝池中的物件。
自動拆箱
- Integer和int型別進行 == > >= < <=比較時,會把Integer自動拆箱
-
Integer和Integer進行 > >= < <=比較時,兩個都會自動拆箱
-
switch會自動拆箱,但是case後面只能是常量 (字面量或者常變數)