1. 程式人生 > >Java Integer(-128~127)值的==和equals比較產生的思考

Java Integer(-128~127)值的==和equals比較產生的思考

java中有兩種型別

基本型別 基本資料類型別存的是數值本身

引用型別 引用型別變數在記憶體放的是資料的引用

基本型別通過==比較的是他們的值大小,而引用型別比較的是他們的引用地址

正文 在一些特殊的類中,如Integer在使用==比較的時候往往非常容易出錯,下面通過幾個例子來探索一下具體的原理

程式碼片段

public class Test03 {

    public static void main(String[] args) {         Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;

        System. out.println( f1 == f2); //true         System. out.println( f3 == f4); //false     } } 當我們給一個Integer賦予一個int型別的時候會呼叫Integer的靜態方法valueOf。  Integer f1 = Integer.valueOf(100);  Integer f2 = Integer.valueOf(100);  Integer f3 = Integer.valueOf(150);  Integer f4 = Integer.valueOf(150);  思考:那麼Integer.valueOf()返回的Integer是不是是重新new Integer(num);來建立的呢?如果是這樣的話,那麼== 比較返回都是false,因為他們引用的堆地址不一樣。

具體來看看Integer.valueOf的原始碼

public static Integer valueOf(int i) {         if (i >= IntegerCache.low && i <= IntegerCache.high)             return IntegerCache.cache[i + (-IntegerCache.low)];         return new Integer(i); }

在IntegerCache中cache陣列初始化如下,存入了-128 - 127的值

cache = new Integer[(high - low) + 1]; int j = low; for( int k = 0; k < cache.length ; k ++)     cache[k] = new Integer(j ++); 從上面我們可以知道給Interger 賦予的int數值在-128 - 127的時候,直接從cache中獲取,這些cache引用對Integer物件地址是不變的,但是不在這個範圍內的數字,則new Integer(i) 這個地址是新的地址,不可能一樣的

程式碼片段

public static void main(String[] args) {     Integer a = new Integer(3);     Integer b = 3;                      int c = 3;     System.out.println(a == b);         System.out.println(a == c);     } a == b分析  Integer b = 3; 自動呼叫Integer.valueOf(3) 返回一個Integer的物件。 這個物件存放到cache中的(上面一段程式碼分析)。 而 Integer a = new Integer(3);這裡建立了一個新的物件Integer 所以 a == b 返回的是false

a == c 分析  一個Integer 與 int比較,先將Integer轉換成int型別,再做值比較,所以返回的是true。

參考資料:《探索java基本型別和包裝型別的使用運算子==進行比較的底層細節》

延伸 java中還有與Integer類似的是Long,它也有一個快取,在區間[-128,127]範圍內獲取快取的值,而Long與long比較的時候先轉換成long型別再做值的比較

Double型別,它沒有快取,但是當Double與double比較的時候會先轉換成double型別,再做值的比較

一道牛客網的習題 

分析:

A: Integer 與 int 比較的時候將Integer轉成int在比價兩個值大小,所以排除  B: Integer i01 = 59;預設處理Integer i01 =Integer.valueOf(59); i01與 i03數值在-128 - 127之間,所以在cache快取中獲取Integer物件,他們引用地址是一樣的。所以排除  C: i03獲取的是cache中快取好的的Integer地址,而i04是重新在堆中建立一個地址,所以兩個地址是不一樣的  D:A一樣的原理。 ---------------------  原文:https://blog.csdn.net/sgls652709/article/details/49079767?utm_source=copy