1. 程式人生 > >包裝類學習(2)

包裝類學習(2)

參考以下文章:

public class TEST {
	    public static void main(String[] args) {
	         
	        Integer a = 1;
	        Integer b = 2;
	        Integer c = 3;
	        Integer d = 3;
	        Integer e = 321;
	        Integer f = 321;
	        Long g = 3L;
	        Long h = 2L;
	        //A
	        System.out.println(c==d);
	        System.out.println(e==f);
	        System.out.println(c==(a+b));
	        System.out.println(c.equals(a+b));
	        System.out.println(g==(a+b));
	        System.out.println(g.equals(a+b));
	        System.out.println(g.equals(a+h));
	        
	        
	        //B
	        int i = 40;  
            int i0 = 40;  
            Integer i1 = 40;  
            Integer i2 = 40;  
            Integer i3 = 0;  
            Integer i4 = new Integer(40);  
            Integer i5 = new Integer(40);  
            Integer i6 = new Integer(0);  
            Double d1=1.0;  
            Double d2=1.0;  
              
            System.out.println("i=i0\t" + (i == i0));  
            System.out.println("i1=i2\t" + (i1 == i2));  
            System.out.println("i1=i2+i3\t" + (i1 == i2 + i3));  
            System.out.println("i4=i5\t" + (i4 == i5));  
            System.out.println("i4=i5+i6\t" + (i4 == i5 + i6));      
            System.out.println("d1=d2\t" + (d1==d2));


	    }
}

反正我是沒做對,和大家分享一下
從兩個部落格找的題目,試了一下答案如下:

true
false
true
true
true
false
true
i=i0	true
i1=i2	true
i1=i2+i3	true
i4=i5	false
i4=i5+i6	true
d1=d2	false

在做題之前先補充點知識:

  • 包裝類的自動拆箱就是運用xxxvalue()方法,自動裝箱是valueof()函式
  • 基本大家都知道,預設情況下,Integer(-127-128)範圍內的值會被快取,但對於其他包裝類卻沒有研究過,下面是其他包裝類的物件的快取機制:
//boolean原生型別自動裝箱成Boolean
    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

    //byte原生型別自動裝箱成Byte
    public static Byte valueOf(byte b) {
        final int offset = 128;
        return ByteCache.cache[(int)b + offset];
    }

    //byte原生型別自動裝箱成Byte
    public static Short valueOf(short s) {
        final int offset = 128;
        int sAsInt = s;
        if (sAsInt >= -128 && sAsInt <= 127) { // must cache
            return ShortCache.cache[sAsInt + offset];
        }
        return new Short(s);
    }

    //char原生型別自動裝箱成Character
    public static Character valueOf(char c) {
        if (c <= 127) { // must cache
            return CharacterCache.cache[(int)c];
        }
        return new Character(c);
    }
    
    //int原生型別自動裝箱成Integer
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

    //int原生型別自動裝箱成Long
    public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

    //double原生型別自動裝箱成Double
    public static Double valueOf(double d) {
        return new Double(d);
    }

    //float原生型別自動裝箱成Float
    public static Float valueOf(float f) {
        return new Float(f);
    }


可以看出除了Double和Float型別基本上都有快取機制,這兩個型別沒有的原因,
可能是double/float的數值不像Integer那樣在指定範圍內只有有限個值,所以效能上不划算

A組

主要的考點是:
當 "=="運算子的兩個運算元都是 包裝器型別的引用,則是比較指向的是否是同一個物件,而如果其中有一個運算元是表示式(即包含算術運算)則比較的是數值(即會觸發自動拆箱的過程)。另外,對於包裝器型別,equals方法並不會進行型別轉換。

c==d 和 e==f j基本操作,沒啥好說
c==(a+b) a和b 先拆箱 在計算  由於(a+b)已經是基本型別了 所以c 拆箱,那麼 3==3 
c.equai(a+b)  會先觸發自動拆箱過程,再觸發自動裝箱過程,也就是說a+b,會先各自呼叫intValue方法,得到了加法運算後的數值之後,便呼叫Integer.valueOf方法,再進行equals比較,Integer 的equals函式如下,結果為true

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
    
g==(a+b) g自動拆箱後,左邊long 右邊int 基本型別比較值,值相等就相等
g.equals(a+b)  Long型別和 Integer肯定不相等
g.equals(a+h)  (a+h) 計算後 自動裝箱加 升級 變成Long的包裝類了

B組

i == i0 和  i1 == i2 基本操作
i1 == i2 + i3  i2和i3會自動拆箱計算 ,i1自動拆箱
i4 == i5 兩個變數 比較 地址 !不牽涉拆箱和裝箱 
i4 == i5 + i6  牽涉拆箱,最後== 兩邊都是int基本型別
d1==d2  Double沒有快取機制!!