【Java基礎】int和Integer
Java中存在8種基本資料型別:byte(8位)、short(16位)、int(32位)、long(64位)、float(32位)、double(64位)、char(16位,0x0000~0xffff)、boolean(true/false) java中不存在無符號數字型別,即C中的unsigned int等 資料型別均有其對應的包裝類,數字型別的包裝類均繼承自Numbers。int對應的包裝類為Integer。
int預設值為0,Integer預設值為null。
要理解int和Integer之間的聯絡和區別,可以通過反編譯及檢視Integer原始碼來學習。
下面看幾個常見例子
//case 1 int int1 = 127; int int2 = 127; //System.out.println(int1 == int2);//true //case 2 Integer integer1 = new Integer(127); Integer integer2 = new Integer(127); //System.out.println(integer1 == integer2);//false //case 3 Integer integer3 = 127; Integer integer4 = 127; //System.out.println(integer3 == integer4);//true //case 4 Integer integer5 = 128; Integer integer6 = 128; //System.out.println(integer5 == integer6);//false //case 5 int int3 = integer3;
case 1:
基本資料型別比較數值。
case 2:
new出來的佔據不同的記憶體空間,比較地址肯定是不一樣的。
case 3和case 4為什麼一個相等一個不相等呢,我們用jad反編譯下,如下:
int int1 = 127; int int2 = 127; Integer integer1 = new Integer(127); Integer integer2 = new Integer(127); Integer integer3 = Integer.valueOf(127); Integer integer4 = Integer.valueOf(127); Integer integer5 = Integer.valueOf(128); Integer integer6 = Integer.valueOf(128); int int3 = integer3.intValue();
可見直接將int值賦給Integer,會自動呼叫Integer的valueOf方法:
private static class IntegerCache { 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; } } * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
檢視原始碼可以看到,IntegerCache會生成一個-128~127的陣列,當呼叫valueOf方法時,如果形參在這個範圍內,則直接返回已經生成的Integer例項,如果超出範圍,才呼叫new Integer()。
所以,case 3中,兩個127賦值為Integer,返回的是都一個例項,所以結果相等;case 4中128超出了範圍,等於兩個均是new Integer(128),所以結果不相等。
這種自動將基本型別轉換成對應包裝器型別的行為,稱為裝箱。
注意:Integer、Short、Byte、Character、Long這幾種的valueOf實現類似,都是生成一定範圍的快取,在範圍內時直接返回例項。
浮點數型的Double、Float卻不同,它們都是直接呼叫new來生成。因為前面幾種都是整數,可以生成一個有限大小的快取,而浮點數辦不到。
case 5:
與case 3相反,將Integer型賦值為int型,通過上面的反編譯可以看到會自動呼叫Integer的intValue方法。
與裝箱相反,這種自動將包裝器型別轉換成基本型別的行為,稱為拆箱。
前面都是相同型別的進行比較,接下來看下int與Integer相互比較會怎麼樣
System.out.println(int1 == integer3);//true
System.out.println((int1 + int2) == integer3);//false
System.out.println(integer3.equals(int1));//true
System.out.println(integer3.equals(int1 + int2));//false
System.out.println(integer3.equals(integer1 + integer2));//false
反編譯得到:
System.out.println(int1 == integer3.intValue());
System.out.println(int1 + int2 == integer3.intValue());
System.out.println(integer3.equals(Integer.valueOf(int1)));
System.out.println(integer3.equals(Integer.valueOf(int1 + int2)));
System.out.println(integer3.equals(Integer.valueOf(integer1.intValue() + integer2.intValue())));
可以看到,Integer型與int型比較時會自動拆箱;而當有算數運算子時,如+等,也會進行拆箱。
後續想到別的再補充。。。