1. 程式人生 > >【Java基礎】int和Integer

【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型比較時會自動拆箱;而當有算數運算子時,如+等,也會進行拆箱。

後續想到別的再補充。。。