Int和Integer的區別

Int和Integer的區別

1、Integer是Int的包裝類,Int是八種基本數據類型之一。
2、Integer變量必須實例化以後纔可以使用,而Int變量不需要實例化。
3、Integer實際是對象的引用,當new一個Integer時,實際上是生成一個指針指向此對象,而Int是直接存儲數據值。
4、Integer的默認值是null,Int的默認值是0。

Int和Integer的比較(擴展)

先來看一段代碼:

public class Test {
    public static void main(String[] args) {

        Integer a = new Integer(10);
        Integer b = new Integer(10);
        System.out.println(a == b);

        Integer c = new Integer(10);
        int d = 10;
        System.out.println(c == d);

        Integer e = new Integer(10);
        Integer f = 10;
        System.out.println(e == f);

        Integer g = 10;
        Integer h = 10;
        System.out.println(g == h);

        Integer i = 128;
        Integer j = 128;
        System.out.println(i == j);

        int k = 10;
        Integer l = 10;
        System.out.println(k == l);

        int m = 128;
        Integer n = 128;
        System.out.println(m == n);

    }

}


輸出結果爲:

思考一下爲什麼?
第一組:

//1、false
        Integer a = new Integer(10);
        Integer b = new Integer(10);
        System.out.println(a == b);

a和b是兩個Integer變量,Integer變量實際上是對Integer對象的引用,而new生成的是兩個對象,內存地址不同,所以a和b不相等,結果爲false。

第二組:

//2、true
        Integer c = new Integer(10);
        int d = 10;
        System.out.println(c == d);

由於包裝類Integer和基本數據類型Int在進行比較的時候,Java會自動拆箱爲Int(c.intValue(10) == d),然後進行比較,實際上就是兩個Int變量的比較,只要兩個變量的值是相等的,結果就爲true。

第三組:

//3、false
        Integer e = new Integer(10);
        Integer f = 10;
        System.out.println(e == f);


和第二組不同的是, e 和 f 都是Integer變量,區別是非new生成的Integer變量 f 指向的是Java常量池中的對象,new生成的Integer變量指向堆中新建的對象,兩者在內存中地址不同,所以結果爲false。

第四組:

//4、true
        Integer g = 10;
        Integer h = 10;
        System.out.println(g == h);


對於 g == h,兩個Integer類的比較應該用equals,而這裏使用==判斷地址,結果本應該是false,但打印出來卻是true,這是爲什麼?
首先,直接聲明Integer g = 10;的時候,Java自動裝箱爲Integer g = Integer.valueOf(10),查看Integer類的valueOf方法:

// range [-128, 127] must be interned (JLS7 5.1.7)
// static final int low = -128;
// assert IntegerCache.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並且 i<=127的時候,第一次聲明會將 i 的值放入緩存中,第二次直接複用緩存裏邊已有的對象,而不是重新創建一個Integer對象。這個區間內的Integer值可以直接使用 == 判斷,但這個區間外的所有數據,都會在堆上產生,並不會複用已有對象。
這組的 g 和 h 都在這個區間內,所以結果爲true。

第五組:

//5、false
        Integer i = 128;
        Integer j = 128;
        System.out.println(i == j);


第五組剛好可以和第四組進行對比,因爲 i 和 j 不在那個區間內,所以都是在堆上新產生一個對象,結果爲false。

第六組:

//6、true
        int k = 10;
        Integer l = 10;
        System.out.println(k == l);


Integer的自動拆箱功能,k == l.intValue(10),也就是比較兩個基本數據類型,結果當然爲true。
第七組:

//7、true
        int m = 128;
        Integer n = 128;
        System.out.println(m == n);


和第六組一樣的道理,總之Int和Integer比較,無論是否有new,結果都爲true,因爲Java會把Integer自動拆箱爲Int再去比較。

再看一段代碼:

public class Test {
    public static void main(String[] args) {

        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;

        Integer e = 321;
        Integer f = 321;

        Long g = 3L;
        Long h = 2L;

        System.out.println(c == d);
        System.out.println(e == f);
        System.out.println(c == (a + b));
        System.out.println(c.equals((a+b)));
        System.out.println(g == (a+b));
        System.out.println(g.equals(a+b));
        System.out.println(g.equals(a+h));

    }

}


輸出結果爲:


c == d就是第一個示例中的第四組,結果爲true。
e == f就是第一個示例中的第五組,結果爲false。
c == (a + b),由於 a + b 包含了算術運算,Java會進行自動拆箱,==又將 c 自動拆箱,所以比較的是數值是否相等,結果爲true。
c.equals((a+b)),a 和 b 先各自調用intValue()方法自動拆箱,得到 a + b 的結果後再調用Integer.valueOf()方法自動裝箱,再進行equals比較,結果爲true。
g == (a+b),首先計算a + b,也是先各自調用intValue()方法自動拆箱得到數值,由於 g 是Long類型的,也會自動拆箱爲long,==運算符能夠將小範圍的數據類型轉換爲大範圍的數據類型,也就是把 int 轉換爲 long,然後把兩個long類型的數值進行比較,結果爲true。
g.equals(a+b),同理a+b會先自動拆箱,然後將結果自動裝箱,但是equals 運算符不會進行類型轉換,所以是Long.equals(Integer),結果爲false。
g.equals(a+h),a + h 自動拆箱後是 int + long,運算符 + 進行類型轉換,結果爲long,long再自動裝箱爲Long,兩個Long進行equals比較,結果爲true。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章