Integer類型與int的==比較


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一樣的原理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM