問題描述:
看如下代碼:
Long a = 128L;
Long b = 128L;System.out.println(a == b);
運行結果如下:
明明 a
和 b
的值一樣,但是結果卻為 False
,為什么同樣的類型,同樣的值,卻不相等,這是為什么呢?
原因分析
那么我們就需要查看一下源碼了
源碼中顯示,Long
中有一個靜態的內部類 LongCache
,專門用于緩存 -128
至 127
之間的值,一共 256
個元素。
如果值在 [-128, 127]
之間,會放在緩存里面,而超過這個范圍就要 new
一個新的對象,也就是說 ==
不能判斷對象是否相等。
當然,如果值是在 [-128, 127]
之間的話是可以正常比較,測不出來什么問題的。
故障解決
1. 使用 .longValue()
比較
Long a = 128L;
Long b = 128L;//System.out.println(a == b);
System.out.println(a.longValue() == b.longValue());
運行結果如下:
2. 使用 .equals()
比較
Long a = 128L;
Long b = 128L;//System.out.println(a == b);
//System.out.println(a.longValue() == b.longValue());
System.out.println(a.equals(b));
運行結果如下:
總結
Long
是 long
的包裝類,而用 Long
聲明的變量其實是對象。在 Java 中,==
運算符用于比較基本數據類型時,比較的是它們的值是否相等;但用于比較對象時,比較的是它們在內存中的地址是否相同。 對于 Long
類型來說,其內部存在 LongCache
這個靜態內部類用于緩存 -128
至 127
之間的值,一共 256
個元素。當創建 Long
類型對象且賦值在這個區間內時,實際上是從緩存中獲取已有的對象,所以使用 ==
比較這些在緩存區間內相同值的對象時,會返回 true
,因為它們指向的是同一個緩存中的對象,內存地址相同。
然而,一旦賦值超出了 [-128, 127]
這個范圍,就會新創建一個 Long
對象,像示例中賦值為 128L
的情況,a
和 b
雖然值相同,但它們是兩個不同的對象,在內存中有不同的地址,所以直接使用 ==
比較就會返回 false
。
- 通過使用
.longValue()
方法,是將Long
對象轉換為基本數據類型long
再進行比較,此時比較的就是具體的數值了,所以只要數值相等就能返回true
。 - 通過使用
.equals()
方法時,Long
類重寫了Object
類的equals()
方法,它是先通過.longValue()
方法獲取Long
對象的基本類型long
的值之后再做比較。
總之,在比較 Long
類型對象的值是否相等時,要謹慎使用 ==
運算符,盡量采用.equals()
的方式來(或者是.longValue()
的方式)確保比較的是實際的數值,避免因對象內存地址不同而導致比較結果不符合預期