Java中“100=100”為true,而"1000=1000"為false?
來源:蘇三說技術
前言
今天跟大家聊一個有趣的話題,在Java中兩個Integer物件做比較時,會產生意想不到的結果。
例如:
Integer a = 100;
Integer b = 100;
System.out.println(a==b);
其執行結果是:true。
而如果改成下面這樣:
Integer a = 1000;
Integer b = 1000;
System.out.println(a==b);
其執行結果是:false。
看到這裡,懵了沒有?
為什麼會產生這樣的結果呢?
1 Integer物件
上面例子中的a和b,是兩個Integer物件。
而非Java中的8種基本型別。
8種基本型別包括:
byte short int long float double boolean char
Integer其實是int的包裝型別。
在Java中,除了上面的這8種型別,其他的型別都是物件,儲存的是引用,而非資料本身。
Integer a = 1000;
Integer b = 1000;
可能有些人認為是下面的簡寫:
Integer a = new Integer(1000);
Integer b = new Integer(1000);
這個想法表面上看起來是對的,但實際上有問題。
在JVM中的記憶體分佈情況是下面這樣的:在棧中建立了兩個區域性變數a和b,同時在堆上new了兩塊記憶體區域,他們存放的值都是1000。
變數a的引用
指向第一個1000的地址。
而變數b的引用
指向第二個1000的地址。
很顯然變數a和b的引用不相等。
既然兩個Integer物件用==號,比較的是引用是否相等,但下面的這個例子為什麼又會返回true呢?
Integer a = 100;
Integer b = 100;
System.out.println(a==b);
不應該也返回false嗎?
物件a和b的引用不一樣。
Integer a = 1000;
Integer b = 1000;
其實正確的簡寫是下面這樣的:
Integer a = Integer.valueOf(1000);
Integer b = Integer.valueOf(1000);
在定義物件a和b時,Java自動呼叫了Integer.valueOf
將數字封裝成物件。而如果數字在low和high之間的話,是直接從IntegerCache
快取中獲取的資料。
Integer類的內部,將-128~127之間的數字快取起來了。
也就是說,如果數字在-128~127,是直接從快取
中獲取的Integer物件。如果數字超過了這個範圍,則是new
出來的新物件。
文章示例中的1000,超出了-128~127的範圍,所以物件a和b的引用指向了兩個不同的地址。
而示例中的100,在-128~127的範圍內,物件a和b的引用指向了同一個地址。
所以會產生文章開頭的執行結果。
為什麼Integer類會加這個快取呢?
答:-128~127是使用最頻繁的數字,如果不做快取,會在記憶體中產生大量指向相同資料的物件,有點浪費記憶體空間。
Integer a = 1000;
Integer b = 1000;
如果想要上面的物件a和b相等,我們該怎麼判斷呢?
2 判斷相等
在Java中,如果使用==
號比較兩個物件是否相等,比如:a==b,其實比較的是兩個物件的引用是否相等。
很顯然變數a和b的引用,指向的是兩個不同的地址,引用肯定是不相等的。
因此下面的執行結果是:false。
Integer a = Integer.valueOf(1000);
Integer b = Integer.valueOf(1000);
System.out.println(a==b);
由於1000在Integer快取的範圍之外,因此上面的程式碼最終會變成這樣:
Integer a = new Integer(1000);
Integer b = new Integer(1000);
System.out.println(a==b);
如果想要a和b比較時返回true,該怎麼辦呢?
答:呼叫equals
方法。
程式碼改成這樣的:
Integer a = Integer.valueOf(1000);
Integer b = Integer.valueOf(1000);
System.out.println(a.equals(b));
執行結果是:true。
其實equals方法是Object類的方法,所有物件都有這個方法。它的底層也是用的==號判斷兩個Object型別的物件是否相等。
不過Integer類對該方法進行了重寫:它的底層會先呼叫Integer類的intValue方法獲取int型別的資料,然後再透過==號進行比較。
此時,比較的不是兩個物件的引用是否相等,而且比較的具體的資料是否相等。
我們使用equals方法,可以判斷兩個Integer物件的值是否相等,而不是判斷引用是否相等。
總結
Integer類中有快取,範圍是:-128~127
。
Integer a = 1000;
其實預設呼叫了Integer.valueOf
方法,將數字轉換成Integer型別:
Integer a = Integer.valueOf(1000);
如果數字在-128~127之間,則直接從快取中獲取Integer物件。
如果數字在-128~127之外,則該方法會new一個新的Integer物件。
我們在判斷兩個物件是否相等時,一定要多注意:
判斷兩個物件的引用是否相等,用==號判斷。 判斷兩個物件的值是否相等,呼叫equals方法判斷。
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70024420/viewspace-3001171/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 為什麼Java中1000==1000為false而100==100為true?JavaFalse
- Java-學習日記(100 == 100為true,1000 == 1000卻為false?)JavaFalse
- Bash 中 SHLVL 變數為 1000 的時候變數
- Counter 1000
- 為你生成了 1000 + 個 ICON For SVGSVG
- Counter with period 1000
- 金士頓A1000 PCIe SSD評測 金士頓A1000 SSD怎麼樣?
- Python爬蟲Post請求返回值為-1000Python爬蟲
- ORA-01795: 列表中的最大表示式數為 1000解決方法
- ORA-01795:列表中的最大表示式數為1000解決方法
- 【FLASH例項1000教程】(4)上
- Oracle常用傻瓜問題1000問Oracle
- BAT機器學習面試1000題系列(二)BAT機器學習面試
- DB2傻瓜1000問(二)DB2
- DB2傻瓜1000問(一)DB2
- SCIE1000 Python and CommunicationIE10Python
- 愛爾蘭一抽獎活動將頭獎設為1000比特幣比特幣
- java尋找100到1000之間能被5和6整除的數Java
- Modis:41%的美國人願意為1000美元洩露隱私資料
- Nginx成為Top1000網站最受歡迎的Web伺服器Nginx網站Web伺服器
- Nginx成為全球TOP1000網站最常用的Web伺服器Nginx網站Web伺服器
- HP MS1000換硬碟過程硬碟
- true || false && falseFalse
- 為什麼會有公司花1000萬請麥肯錫解決問題?
- DB2常用傻瓜問題1000問DB2
- 1000 千米高空俯瞰 React NativeReact Native
- 驚!1周處理1000個需求?
- page_cleaner: 1000ms intended loop tookOOP
- Topcoder SRM646 DIV2 1000
- 計算1000以內所有偶數和.
- 一次提速1000倍的delete操作delete
- Failure to extend rollback segment 2 because of 1000 conditionAI
- 阿里雲1000元代金券大禮包限量領取中阿里
- 我從 1000 份程式碼審查中學到了什麼
- 遊戲角色撞臉明星,就得賠1000萬美元?遊戲
- 前端面試每日 3+1 —— 第1000天前端面試
- sql server如何刪除前1000行資料SQLServer
- 雲手遊平臺Artie完成1000萬美元融資