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型比較時會自動拆箱;而當有算術運算符時,如+等,也會進行拆箱。
後續想到別的再補充。。。