其他網址
JAVA中Long與Integer比較容易犯的錯誤(比較數據equals)_java_我主要負責轉載優秀的技術博文-CSDN博客
另見:《Java開發實戰經典》=> 6.12 包裝類
簡介
問題起源:Long或Integer如何比較大小呢?
- 錯誤方法:
直接使用==來比較。 因爲Long與Ineger都是包裝類型,是對象。 而不是普通類型long與int
使用equals方法。因爲equals方法只能比較同類型的類,例如兩個都要是Integer類型。- 正確方法:用,或者先使用longValue()或intValue()方法來得到他們的基本類型的值然後使用==比較也是可以的。
拆箱與裝箱原理
裝箱就是將基本數據類型轉化爲包裝類型,那麼拆箱就是將包裝類型轉化爲基本數據類型。
package org.example.a; public class Demo{ public static void main(String[] args) { //自動裝箱,底層其實執行了Integer a=Integer.valueOf(1); Integer a = 10; //自動拆箱,底層其實執行了int b=a.intValue(); int b = a; } }
查看反彙編文件
依次執行如下命令
javac -d . org\example\a\Demo.java
javap -c org.example.a.Demo
輸出結果如下:
E:\work\idea_proj\test_java\src>javap -c org.example.a.Demo
Compiled from "Demo.java"
public class org.example.a.Demo {
public org.example.a.Demo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: returnpublic static void main(java.lang.String[]);
Code:
0: bipush 10
2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: aload_1
7: invokevirtual #3 // Method java/lang/Integer.intValue:()I
10: istore_2
11: return
}
Integer a = 10;
執行上面那句代碼的時候,系統爲我們執行了:Integer a = Integer.valueOf(10);int b = a;
執行上面那句代碼的時候,系統爲我們執行了:int b = a.intValue();
緩存問題
分析過程
其他網址
測試代碼
package org.example.a;
public class Demo{
public static void main(String[] args) {
Integer a = 100;
Integer b = 100;
Integer c = 200;
Integer d = 200;
System.out.println(a == b);
System.out.println(c == d);
}
}
執行結果
true
false
原因:
Integer有個緩存,原理如下。
valueOf源碼
//private static class IntegerCache { // static final int low = -128; // static final int high = 127; public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
當i的值位於[-128,127]的時候,會直接返回Integer緩存數組中相應對象的引用,如果i大於127或小於-128,會重新創建一個Integer實例,並返回。
那麼第一條式子a和b的值都在緩存範圍內,因此他們指向同一個對象,因此返回true。c和d的值不在範圍內,都是通過new創建出來的,因此不是同一個對象,返回false。
其他包裝類的緩存
Byte、Short、Integer、Long、Character的valueOf()實現機制類似。
包裝類 | 說明 |
Byte | 相同值的Byte比較永遠返回true。因爲byte取值範圍就是[-128,127]。 |
Short、Integer、Long | 相同值在[-128,127]則返回true,不在則返回false |
Character | 要返回true,只需保證i <= 127。因爲char最小值爲0,本來就大於等於-128。 |
Float、Double | 永遠返回false。因爲其永遠返回新創建的對象,因爲一個範圍內的整數是有限的,但是小數卻是無限的,無法保存在緩存中。 |
Boolean | 只有兩個對象,要麼是true的Boolean,要麼是false的Boolean,只要boolean的值相同,Boolean就相等。 |