天天看點

Java自動裝箱與自動拆箱了解

  1. 首先我們要明白什麼是基本類型與基本類型的包裝類的概念。

        java中的int,byte,long等等都是基本類型;其對應的Integer,Byte,Long等等都是基本類型的包裝類。

Java自動裝箱與自動拆箱了解
  1. 自動裝箱與拆箱

        基本類型可以使用運算符直接進行計算,但是引用類型不可以,而基本類型包裝類作為引用類型的一種卻可以計算,這就是因為java中自動為我們做好了Integer轉換成int類型,這就是自動拆箱。

        相應地,引用資料類型變量的值必須是new出來的記憶體空間位址值,而我們可以将一個基本類型的值指派給一個基本類型包裝類的引用,這就是因為java中自動為我們做好了int類型轉換成Integer類型,這就是自動裝箱。

Integer i = 5;//自動裝箱。相當于Integer i = Integer.valueOf(5);
i = i + 1;//等号右邊:将i對象轉成基本數值(自動拆箱) i.intValue() + 1; 加法運算完成後,再次裝箱,把基本數值轉成對象。
           

    但是我們注意這裡有一個坑,因為Integer是引用類型的,是以我們可以将其值設定為null,那麼此時如果将null指派給i,再将i+1就會報錯,是以這邊就需要去判空。

Integer i = null;
if(i != null){//這裡我們經常在寫web程式的時候會發生這樣的錯誤
     i = i + 1;
 }else{
     i = 5;
 }
           
  1. 接下來說說int和Integer的差別吧,面試的時候也經常問到

    (1)Integer是int的包裝類;int是基本資料類型;

    (2)Integer變量必須執行個體化後才能使用;int變量不需要;

    (3)Integer實際是對象的引用,指向此new的Integer對象;int是直接存儲資料值 ;

    (4)Integer因為是包裝類,屬于引用類型,是以其預設值是null;int的預設值是0。

  • 對于Integer來說,他其實是個引用,既然是引用,那麼就可以new對象,既然是new的對象,那麼兩個對象的記憶體位址就一定不會相同,是以兩個變量就不會相等
Integer i = new Integer(100);
Integer j = new Integer(100);
System.out.println(i == j); //false
           
  • 同樣的,如果一個Integer是new出來的,而另外一個Integer不是new出來的,他們的結果也不相同(因為new出來的Integer生成的變量是指向堆中的,而非new生成的Integer是指向java常量池中的對象。那麼兩者的記憶體位址就不一樣)
Integer i = new Integer(100);
Integer j = 100;
System.out.println(i == j); //false
           
  • 對于兩個非new生成的Integer對象,進行比較時,如果兩個變量的值在區間-128到127之間,則比較結果為true,如果兩個變量的值不在此區間,則比較結果為false
Integer i = 100;
Integer j = 100;
System.out.println(i == j); //true
/*********************************************/
Integer i = 128;
Integer j = 128;
System.out.println(i == j); //false
/*********************************************/
/*針對以上原因做一個解釋:java在編譯Integer i = 100 時,會翻譯成為Integer i = Integer.valueOf(100),
java中Integer類型的valueOf的定義如下,對于-128到127之間的數,會進行緩存,Integer i = 127時,
會将127進行緩存,下次再寫Integer j = 127時,就會直接從緩存中取,就不會new了*/
//以下是valueOf的源碼
public static Integer valueOf(int i){
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high){
        return IntegerCache.cache[i + (-IntegerCache.low)];
    }
    return new Integer(i);
}
           
  1. 最後來談一下valueOf和parseInt的差別(兩者的傳回類型不同)

    (1)Integer.valueOf(String),這個是将String類型轉成了Integer對象;

    (2)Integer.parseInt(String),這個是将String類型的對象轉成了int類型;

//源碼如下
//valueOf中其實是調用了parseInt的方法的。
 public static Integer valueOf(String s) throws NumberFormatException {
   return Integer.valueOf(parseInt(s, 10));
 }
 /***************************************************************/
public static int parseInt(String s) throws NumberFormatException {
   return parseInt(s,10);
 }