從JDK5後開始,爲了減少開發人員的工作,Java提供了自動拆箱與自動裝箱功能,下面就來講解一下其內容
- 自動裝箱:把基本類型轉換爲包裝類類型
- 自動拆箱:把包裝類類型轉換爲基本類型
原理:自動裝箱都是通過包裝類的valueOf()方法來實現的.自動拆箱都是通過包裝類對象的xxxValue()來實現的。
好處:讓基本類型也具有對象的特徵,就出現了包裝類型,將基本類型“包裝起來”,使得它具有了對象的性質,並且爲其添加了屬性和方法,豐富了基本類型的操作,大大提高了開發效率
Integer num =5; //自動裝箱
5是int類型,如果要把int類型賦值給Integer包裝類,就需要自動裝箱,相當於Integer num=Integer.ValueOf(5).
Integer a = new Integer(5); //自動拆箱
int b= a;
b是包裝類,a=b是把b賦值給a,那麼b這個包裝類需要自動拆箱,相當於int a = b.intValue();
我們舉幾個例子來着重理解一下自動裝箱和拆箱機制
==符號判斷的是a和b在堆中所指向的對象是不是同一個;equals比較兩個對象其結果是true當且僅當該參數不是null並且是Integer對象包含相同int值。
// 題目一
Integer i1 = new Integer(97);
Integer i2 = new Integer(97);
System.out.println(i1 == i2); //false
System.out.println(i1.equals(i2)); //true
System.out.println("-----------");
// 題目二
Integer i3 = 127;
Integer i4 = 127;
System.out.println(i3 == i4); //true
System.out.println(i3.equals(i4)); //true
System.out.println("-----------");
// 題目三
Integer i5 = 128;
Integer i6 = 128;
System.out.println(i5 == i6);
System.out.println(i5.equals(i6)); //true
// 題目四
int i7=59;
Integer i8=new Integer(59);
System.out.println(i7==i8); //true
題目一:爲false的原因是生成了兩個不同的對象i1,i2存放於堆中,那麼這個結果就一定是false;equals結果只要兩值相等就爲true。
題目2:因爲127這個值介於-128到127之間,在java內存的常量池中會存放一個127的常量,然後i3,i4兩個對象都指向常量池中的127,所以判斷爲true。
題目3:因爲129這個值超出了-128到127這個範圍了,所以引用就不向常量池中進行引用了,就會重新生成一個129的Integer對象,故而i5,i6兩個是不同對象,所以是false。
題目4:i7==i8是比較i7,i8;i7是基本數據類型,i8是包裝類,這個時候包裝類就會自動調用intValue()方法轉換爲基本數據類型,從而和i7就是相等的,所以爲true。
這個源碼就可以解釋題目二的原理: **-128到127是byte的取值範圍,如果在這個取值範圍內,自動裝箱就不會新創建對象,而是從常量池中獲取,如果超過了byte取值範圍就會再新創建對象。**
public static Integer valueOf(int var0) {
return var0 >= -128 && var0 <= IntegerCache.high ? IntegerCache.cache[var0 + 128] : new Integer(var0);
}
注意:除double和float兩種類型以外,其他基本類型入Integer值在 -128 ~ 127之間時不會新建一個Integer 對象而是從緩存中獲取。所以在做 == 判斷時要注意值的大小,如果超過範圍,則兩個值 即使一樣但 == 比較的結果還是false。