本人曾經實習面試的時候遇到的一個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
以上都是本人自己的理解過,若有不妥之處,請指正!