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-學習日記(100 == 100為true,1000 == 1000卻為false?)JavaFalse
- true || false && falseFalse
- Ruby中的true和falseFalse
- 為你生成了 1000 + 個 ICON For SVGSVG
- 密歇根大學:研究顯示人們願意為了1000美元而棄用Facebook
- WPF ClipToBounds True or falseFalse
- WIN10系統如何檢視網路卡是100m還是1000m WIN10網路卡是100m還是1000m怎麼檢視Win10
- peewee 的 BooleanField 是翻譯為 tinyint(1) 還是 enum('true','false')?BooleanFalse
- Python解惑:True與FalsePythonFalse
- mysql資料庫中tinyint(1) 儲存數字時候取值為True、False解釋MySql資料庫False
- 央視新聞《1000本金一年賺100萬》手機搜狐網
- Python爬蟲Post請求返回值為-1000Python爬蟲
- js中return、return true、return false的區別JSFalse
- 為什麼 [] == ![] 為 true?
- Counter 1000
- 【Flutter 專題】100 何為 Flutter Widgets ?Flutter
- js判斷true和false一覽JSFalse
- Counter with period 1000
- 華為GaussDB T(Gaussdb 100) 安裝系列一
- 月薪100k+ 華為招聘遊戲人才遊戲
- VX1000_IntegrationForTricore
- Java解析並修改JSON:將isShow屬性改為falseJavaJSONFalse
- 福布斯:2020年全球品牌價值100強 中國華為入榜
- js中bool值為false的幾種情況JSFalse
- 做「容量預估」可沒有true和falseFalse
- Java 100道演算法Java演算法
- 446、Java框架100 -【MyBatis - if】 2020.12.23Java框架MyBatis
- HttpContext.User.Identity.IsAuthenticated 為falseHTTPContextIDEFalse
- SCIE1000 Python and CommunicationIE10Python
- 100+標杆案例和1個減法:華為“懂行100”給2021帶來了什麼?
- Chrome OS 100 為 Chromebook 帶來全新功能設計!Chrome
- 『Java 語法基礎』3 * 0.1 == 0.3 將會返回什麼?true 還是 false?JavaFalse
- Airbnb:2018年Airbnb為全球帶來直接經濟影響超1000億美元AI
- 為什麼會有公司花1000萬請麥肯錫解決問題?
- 糖博士100,助你健康100
- java1-100隨機數Java隨機
- leetcode 100.相同的樹 JavaLeetCodeJava
- js五種為false的判斷JSFalse