Java中Integer.equals的用法與特殊情況
在 Java 中,Integer.equals 是 Integer 類的一個方法,用于比較兩個 Integer 對象的值是否相等。雖然它看起來很簡單,但在某些情況下可能會出現(xiàn)意想不到的行為。
本文將深入剖析 Integer.equals 的工作原理,并探討可能出現(xiàn)的特殊情況。
1.Integer.equals的基本規(guī)則
Integer 繼承自 Number 類,并重寫了 equals 方法,源碼如下:
@Override
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return this.intValue() == ((Integer) obj).intValue();
}
return false;
}
規(guī)則解析:
- 首先檢查
obj是否是Integer實(shí)例,如果不是,直接返回false。 - 如果是
Integer,則比較其int值(intValue())。
示例:
Integer a = 1000; Integer b = 1000; System.out.println(a.equals(b)); // true,因?yàn)?1000 == 1000
盡管 a 和 b 可能是不同的對象(因?yàn)?1000 超出了 Java 緩存范圍),但 equals 只比較 值,所以返回 true。
2.Integer.equals(int)的裝箱問題
在 Integer.equals 方法中,參數(shù) Object obj 可能是 自動裝箱 過來的 Integer,也可能是直接傳入的 int。
Java 提供了 自動裝箱(Autoboxing) 機(jī)制,會將基本類型 int 轉(zhuǎn)換成 Integer。
示例:
Integer a = 1000; System.out.println(a.equals(1000)); // true
發(fā)生了什么?
1000是int,但equals(Object obj)需要Object,所以1000先被 自動裝箱 為Integer.valueOf(1000)。a.equals(Integer.valueOf(1000)),進(jìn)入equals方法后,obj是Integer實(shí)例,因此比較intValue(),返回true。
特殊情況:
Integer a = 1000; System.out.println(a.equals(1000.0)); // false
1000.0是double,不會被裝箱為Integer,obj instanceof Integer返回false,所以equals直接返回false。
3.==vsequals()
示例:
Integer x = 100; Integer y = 100; System.out.println(x == y); // true System.out.println(x.equals(y)); // true Integer a = 1000; Integer b = 1000; System.out.println(a == b); // false System.out.println(a.equals(b)); // true
為什么100和1000處理不同?
- Java 對
-128 ~ 127之間的Integer進(jìn)行了緩存(Integer Cache),相同數(shù)值的Integer會共享同一個對象,==也成立。 - 超過
127的數(shù)值 不在緩存范圍內(nèi),Integer.valueOf(1000)會創(chuàng)建新對象,所以==比較的是不同的對象地址,返回false。
如何正確判斷 Integer 相等?
- ? 推薦使用
equals,避免緩存帶來的困惑:
Integer a = 1000; Integer b = 1000; System.out.println(a.equals(b)); // true(比較的是值)
- ? 不要直接用
==,可能會出問題:
Integer a = 1000; Integer b = 1000; System.out.println(a == b); // false(因?yàn)槭遣煌膶ο螅?
4.null處理
示例:
Integer a = null; System.out.println(a.equals(1000)); // 運(yùn)行時報錯:NullPointerException
如果 a 為 null,那么調(diào)用 a.equals() 時會發(fā)生 NullPointerException。
因此,在比較 Integer 時,建議使用 Objects.equals() 來防止空指針異常:
Integer a = null; System.out.println(Objects.equals(a, 1000)); // false,不會報錯
Objects.equals(a, b) 的實(shí)現(xiàn)相當(dāng)于:
(a == b) || (a != null && a.equals(b))
這樣就能避免 null.equals() 造成的異常。
5.equals()與compareTo()的區(qū)別
在 Integer 中,compareTo() 也是一個常見的比較方法:
Integer a = 1000; Integer b = 2000; System.out.println(a.compareTo(b)); // -1(1000 小于 2000) System.out.println(b.compareTo(a)); // 1(2000 大于 1000) System.out.println(a.compareTo(1000)); // 0(相等)
區(qū)別:
equals() 只返回 true/false,用于判斷 相等性。
compareTo() 返回:
負(fù)數(shù)(this < other)0(this == other)正數(shù)(this > other)
6. 總結(jié)
| 情況 | 代碼示例 | 結(jié)果 | 原因 |
|---|---|---|---|
| equals() 比較兩個 Integer | new Integer(1000).equals(new Integer(1000)) | ? true | 比較的是數(shù)值 |
| equals() 直接比較 int | Integer.valueOf(1000).equals(1000) | ? true | 1000 先裝箱為 Integer(1000),再比較值 |
| equals() 與 Double | Integer.valueOf(1000).equals(1000.0) | ? false | 1000.0 是 Double,equals() 只支持 Integer |
| == 比較 Integer(緩存范圍內(nèi)) | Integer x = 100; Integer y = 100; x == y | ? true | -128 ~ 127 之間 Integer 復(fù)用同一對象 |
| == 比較 Integer(超出緩存范圍) | Integer a = 1000; Integer b = 1000; a == b | ? false | 1000 超出緩存范圍,創(chuàng)建的是兩個對象 |
| null.equals() | Integer a = null; a.equals(1000); | ? 拋異常 | a 為 null,調(diào)用 equals() 報 NullPointerException |
| Objects.equals() | Objects.equals(null, 1000); | ? false | 避免 null 異常 |
Integer.equals(Object obj) 只比較值,不管對象地址。
Integer 的 -128 ~ 127 之間的值會被緩存,超出范圍的 Integer 不能用 == 比較。
如果 Integer 可能為 null,用 Objects.equals(a, b) 避免空指針異常。
Integer.equals(Double) 直接返回 false,不會自動轉(zhuǎn)換類型。
compareTo() 適用于大小比較,而 equals() 只判斷相等性。
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java17中record替代Lombok部分功能使用場景探究
這篇文章主要介紹了使用Java17中的record替代Lombok的部分功能,本文來為大家小小的總結(jié)下,我們可以在哪些地方,利用record來替換Lombok2024-01-01
使用SSE流式輸出實(shí)戰(zhàn)記錄(Javaweb前后端)
這篇文章主要介紹了使用SSE流式輸出(Javaweb前后端)的相關(guān)資料,SSE是一種允許服務(wù)器向客戶端推送實(shí)時數(shù)據(jù)的技術(shù),適用于聊天應(yīng)用、實(shí)時數(shù)據(jù)監(jiān)控等場景,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-05-05
詳解IDEA 啟動tomcat 端口占用原因以及解決方法( 使用debug模式)
這篇文章主要介紹了詳解IDEA 啟動tomcat 端口占用原因以及解決方法( 使用debug模式) ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08
Spring boot工具類靜態(tài)屬性注入及多環(huán)境配置詳解
這篇文章主要為大家詳細(xì)介紹了Spring boot工具類靜態(tài)屬性注入,及多環(huán)境配置詳解,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
Java快速實(shí)現(xiàn)Word轉(zhuǎn)圖片功能的多種方法與實(shí)踐
在軟件開發(fā)中,轉(zhuǎn)換文件格式是一個常見需求,尤其是將Word文件轉(zhuǎn)換為圖片格式,這在報表生成、文檔預(yù)覽、自動化處理等場景中非常有用,在 Java 中實(shí)現(xiàn)Word轉(zhuǎn)圖片的功能有多種思路,以下將介紹幾種常見的實(shí)現(xiàn)方式,并探討它們的優(yōu)缺點(diǎn),需要的朋友可以參考下2025-08-08
解決mybatis-plus新增數(shù)據(jù)自增ID變無序問題
這篇文章主要介紹了解決mybatis-plus新增數(shù)據(jù)自增ID變無序問題,具有很好的參考價值,希望對大家有所幫助。2023-07-07
Java實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)(借助Array?List)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),借助Array?List,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
SpringBoot2 實(shí)現(xiàn)JPA分頁和排序分頁的案例
這篇文章主要介紹了SpringBoot2 實(shí)現(xiàn)JPA分頁和排序分頁的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01

