Integer.valueOf(String) 方法之惑
http://www.importnew.com/9162.html
Importnew注:如果你也對(duì)Java技術(shù)翻譯分享感興趣,歡迎加入我們的Java開發(fā)小組。參與方式請(qǐng)查看小組簡(jiǎn)介。
有個(gè)仁兄在 StackOverflow 上發(fā)起了一個(gè)問題,是這么問的:
“ 我被下面的代碼搞暈了,為什么它們會(huì)返回不同的值?”
| 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")); |
輸出是:
| 1 2 3 | true false true |
為什么第一個(gè)判斷返回了true而第二個(gè)判斷返回了false?127和128有什么我不知道的區(qū)別嗎?(當(dāng)然除了127小于128…)
還有,為什么第三個(gè)判斷返回了true?
我看了另一個(gè)相關(guān)提問的回答,但是我還是不知道它們什么時(shí)候返回true還有為什么第二個(gè)判斷返回false。
回答#1:
Integer.valueOf(String)確有一個(gè)不同尋常的行為。
valueOf會(huì)返回一個(gè)Integer(整型)對(duì)象,當(dāng)被處理的字符串在-128和127(包含邊界)之間時(shí),返回的對(duì)象是預(yù)先緩存的。這就是為什么第一行的調(diào)用會(huì)返回true-127這個(gè)整型對(duì)象是被緩存的(所以兩次valueOf返回的是同一個(gè)對(duì)象)——第二行的調(diào)用返回false是因?yàn)?28沒有被緩存,所以每次調(diào)用,都會(huì)生成一個(gè)新的整型對(duì)象,因此兩個(gè)128整型對(duì)象是不同的對(duì)象。
重要的是你要知道在上面的比較中,你實(shí)際進(jìn)行比較的是integer.valueOf返回的對(duì)象引用,所以當(dāng)你比較緩存外的整型對(duì)象時(shí),相等的判斷不會(huì)返回true,就算你傳個(gè)valueOf的值是相等的也沒用。(就像第二行中Integer.valueOf(128)==Integer.valueOf(128))。想讓這個(gè)判斷返回true,你需要使用equals()方法。
parseInt()返回的不是整型對(duì)象,而是一個(gè)int型基礎(chǔ)元素。這就是為什么最后一個(gè)判斷會(huì)返回true,第三行的判斷中,在判斷相等時(shí),實(shí)際比較的是128 == 128,所以它必然是相等的。
再來說說第三種比較中的一點(diǎn)區(qū)別,使得它的結(jié)果與第二種比較不一樣了:
一個(gè)unboxing conversion(一種比較時(shí)的轉(zhuǎn)換,把對(duì)對(duì)象的引用轉(zhuǎn)換為其對(duì)應(yīng)的原子類型)在第三行的比較中發(fā)生了。因?yàn)楸容^操作符使用了==同時(shí)等號(hào)的兩邊存在一個(gè)int型和一個(gè)Integer對(duì)象的引用。這樣的話,等號(hào)右邊返回的Integer對(duì)象被進(jìn)一步轉(zhuǎn)換成了int數(shù)值,才與左邊進(jìn)行相等判斷。
所以在轉(zhuǎn)換完成后,你實(shí)際比較的是兩個(gè)原子整型數(shù)值。這種轉(zhuǎn)換正是你在比較兩個(gè)原子類型時(shí)所期待看到的那樣,所以你最終比較了128等于128。
回答#2:
Integer類有一個(gè)靜態(tài)緩存,存儲(chǔ)了256個(gè)特殊的Integer對(duì)象——每個(gè)對(duì)象分別對(duì)應(yīng)`-128 和127之間的一個(gè)值。
有了這個(gè)概念,就可以知道上面三行代碼之間的區(qū)別。
| 1 | new Integer(123); |
顯示創(chuàng)建了一個(gè)新的Integer對(duì)象。
| 1 | Integer.parseInt("123"); |
解析完字符串后返回一個(gè)int值。
| 1 | Integer.valueOf("123"); |
這種情況比其他的要更復(fù)雜一些。首先進(jìn)行了字符串解析,然后如果解析的值位于-128和127之間,就會(huì)從靜態(tài)緩存中返回對(duì)象。如果超出了這個(gè)范圍,就會(huì)調(diào)用Integer()方法并將解析的值作為參數(shù)傳入,得到一個(gè)新的對(duì)象。
現(xiàn)在,讓我們看一下問題中的3個(gè)表達(dá)式。
| 1 | Integer.valueOf("127")==Integer.valueOf("127"); |
上面的表達(dá)式返回true,因?yàn)镮nteger的值從靜態(tài)緩存中取了2次,表達(dá)式返回了對(duì)象與自己比較的結(jié)果。因?yàn)橹挥幸粋€(gè)Integer對(duì)象,所以返回結(jié)果為true。
| 1 | Integer.valueOf("128")==Integer.valueOf("128"); |
上面的表達(dá)式返回false,因?yàn)?28沒有存在靜態(tài)緩沖區(qū)。所以每次在判斷相等時(shí)等式兩邊都會(huì)創(chuàng)建新的Integer對(duì)象。由于兩個(gè)Integer對(duì)象不同,所以==只有等式兩邊代表同一個(gè)對(duì)象時(shí)才會(huì)返回true。因此,上面的等式返回false。
| 1 | Integer.parseInt("128")==Integer.valueOf("128"); |
上面的表達(dá)式比較的是左邊的原始int值128與右邊新創(chuàng)建的Integer對(duì)象。但是因?yàn)閕nt和Integer之間比較是沒有意義的,所以Java在進(jìn)行比較前會(huì)將Integer自動(dòng)拆箱,所以最后進(jìn)行的是int和int值之間的比較。由于128和自己相等,所以返回true。
原文鏈接:? stackoverflow ?翻譯:? ImportNew.com? -? 靳禹譯文鏈接:? http://www.importnew.com/9162.html
[? 轉(zhuǎn)載請(qǐng)保留原文出處、譯者和譯文鏈接。 ]
總結(jié)
以上是生活随笔為你收集整理的Integer.valueOf(String) 方法之惑的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 内存泄露
- 下一篇: 大数据量下的sort