本文由 ImportNew - 靳禹 翻譯自 stackoverflow。如需轉載本文,請先參見文章末尾處的轉載要求。
html
Importnew注:若是你也對Java技術翻譯分享感興趣,歡迎加入咱們的Java開發小組。參與方式請查看小組簡介。java
有個仁兄在 StackOverflow 上發起了一個問題,是這麼問的:緩存
「 我被下面的代碼搞暈了,爲何它們會返回不一樣的值?」oracle
1
2
3
|
System.out.println(Integer.valueOf(
"127"
)==Integer.valueOf(
"127"
));
System.out.println(Integer.valueOf(
"128"
)==Integer.valueOf(
"128"
));
System.out.println(Integer.parseInt(
"128"
)==Integer.valueOf(
"128"
));
|
輸出是:spa
1
2
3
|
true
false
true
|
爲何第一個判斷返回了true
而第二個判斷返回了false
?127
和128
有什麼我不知道的區別嗎?(固然除了127
小於128
…)
還有,爲何第三個判斷返回了true
?
我看了另外一個相關提問的回答,可是我仍是不知道它們何時返回true還有爲何第二個判斷返回false
。翻譯
回答#1:code
Integer.valueOf(String)
確有一個不一樣尋常的行爲。htm
valueOf
會返回一個Integer
(整型)對象,當被處理的字符串在-128
和127
(包含邊界)之間時,返回的對象是預先緩存的。這就是爲何第一行的調用會返回true
-127
這個整型對象是被緩存的(因此兩次valueOf
返回的是同一個對象)——第二行的調用返回false
是由於128
沒有被緩存,因此每次調用,都會生成一個新的整型對象,所以兩個128
整型對象是不用的對象。對象
重要的是你要知道在上面的比較中,你實際進行比較的是integer.valueOf
返回的對象引用,因此當你比較緩存外的整型對象時,相等的判斷不會返回true
,就算你傳個valueOf
的值是相等的也沒用。(就像第二行中Integer.valueOf(128)==Integer.valueOf(128))
。想讓這個判斷返回true
,你須要使用equals()
方法。ci
parseInt()
返回的不是整型對象,而是一個int
型基礎元素。這就是爲何最後一個判斷會返回true
,第三行的判斷中,在判斷相等時,實際比較的是128 == 128
,因此它必然是相等的。
再來講說第三種比較中的一點區別,使得它的結果與第二種比較不同了:
一個unboxing conversion(一種比較時的轉換,把對對象的引用轉換爲其對應的原子類型)在第三行的比較中發生了。由於比較操做符使用了==
同時等號的兩邊存在一個int
型和一個Integer
對象的引用。這樣的話,等號右邊返回的Integer
對象被進一步轉換成了int
數值,才與左邊進行相等判斷。
因此在轉換完成後,你實際比較的是兩個原子整型數值。這種轉換正是你在比較兩個原子類型時所期待看到的那樣,因此你最終比較了128
等於128
。
回答#2:
Integer
類有一個靜態緩存,存儲了256個特殊的Integer
對象——每一個對象分別對應`-128 和127之間的一個值。
有了這個概念,就能夠知道上面三行代碼之間的區別。
1
|
new Integer(123);
|
顯示建立了一個新的Integer
對象。
1
|
Integer.parseInt(
"123"
);
|
解析完字符串後返回一個int
值。
1
|
Integer.valueOf(
"123"
);
|
這種狀況比其餘的要更復雜一些。首先進行了字符串解析,而後若是解析的值位於-128
和127
之間,就會從靜態緩存中返回對象。若是超出了這個範圍,就會調用Integer()
方法並將解析的值做爲參數傳入,獲得一個新的對象。
如今,讓咱們看一下問題中的3個表達式。
1
|
Integer.valueOf(
"127"
)==Integer.valueOf(
"127"
);
|
上面的表達式返回true
,由於Integer
的值從靜態緩存中取了2次,表達式返回了對象與本身比較的結果。由於只有一個Integer對象,因此返回結果爲true
。
1
|
Integer.valueOf(
"128"
)==Integer.valueOf(
"128"
);
|
上面的表達式返回false
,由於128
沒有存在靜態緩衝區。因此每次在判斷相等時等式兩邊都會建立新的Integer
對象。因爲兩個Integer
對象不一樣,因此==
只有等式兩邊表明同一個對象時纔會返回true
。所以,上面的等式返回false
。
1
|
Integer.parseInt(
"128"
)==Integer.valueOf(
"128"
);
|
上面的表達式比較的是左邊的原始int
值128
與右邊新建立的Integer
對象。可是由於int
和Integer
之間比較是沒有意義的,因此Java在進行比較前會將Integer自動拆箱,因此最後進行的是int
和int
值之間的比較。因爲128
和本身相等,因此返回true
。
原文連接: stackoverflow 翻譯: ImportNew.com - 靳禹
譯文連接: http://www.importnew.com/9162.html
[ 轉載請保留原文出處、譯者和譯文連接。]