java中自動裝箱拆箱的陷阱


本人曾經實習面試的時候遇到的一個java自動裝箱的陷阱,當時就是不太明白,回來自己琢磨了一下這個問題,在此作爲總結,

希望讓剛開始接觸java的同學以後避免這個坑!

好了廢話不多說,直接貼出這段代碼:

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;
		 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));	        
	}
大家看到這段代碼不妨自己先琢磨一下答案,這其實就是java自動裝箱的一個非常常見的陷阱。在講解這個問題之前,非常有必要

來說一個java規範:特定的基本類型一定得被box成相同的包裝類型。這些對象會被高速緩存以重複使用,並且會被當做一般對象使用。

這些特殊的值是boolean值的true和false、所有的byte值、介於-128至127的short與int值,以及介於\u0000與\u007F之間的任何一個char

大家在理解上面所說的java規範,可能前兩條的結果大家已經可以的出來了,由於介於-128至127的int值都會被高速緩存以重複

使用,所以第一個輸出的結果爲true。相反第二條輸出的結果爲false。

接下來再來講解後面四條輸出語句,首先我們先來說說(a+b)這個過程,其實這個過程是一個拆箱相加,然後裝箱的過程。就是讓a、b

先拆箱成int類型相加,然後在裝箱成Integer類型去和c比較。這樣大家應該猜到第3和第5輸出語句都爲true。

最後再來說一說第4和第6兩條輸出語句,如果我們在eclipse中,我們首先可以Ctrl第4條輸出語句的equals方法,看看裏面的源代碼:

 public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
如果大家理解了(a+b)過程,那麼自然就會得到答案,因爲傳入的參數確實爲Integer類型,所以第4條語句的結果爲true。接着我們

可以Ctrl第6條輸出語句的equals方法:

public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }
因爲傳入的參數爲Integer類型,所以 if條件判斷不成立,返回false。所以最後一條輸出語句的結果爲false。


最後貼上答案:

true
false
true
true
true
false

以上都是本人自己的理解過,若有不妥之處,請指正!





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章