首頁 > Java > java教程 > 主體

談談Java資料型別中自動封裝拆箱與實例分析

零下一度
發布: 2017-06-23 10:04:21
原創
1889 人瀏覽過

目的:

自動裝箱和拆箱從Java 1.5開始引入,目的是將原始型別值轉自動地轉換成對應的物件,以使用物件的API和參考類型操作。自動裝箱與拆箱的機制可以讓我們在Java的變數賦值或是方法呼叫等情況下使用原始型別或物件型別更簡單直接。

定義:

#自動組裝就是Java自動將原始型別值轉換成對應的對象,例如將int的變數轉換成Integer對象,這個過程叫做裝箱,反之將Integer物件轉換成int型別值,這個過程叫做拆箱。因為這裡的裝箱和拆箱是自動進行的非人為轉換,所以就稱為自動裝箱和拆箱。原始型別byte,short,char,int,long,float,doubleboolean#對應的封裝類別為Byte,Short,Character,Integer,Long,Float,Double,Boolean

實作:

自動裝箱時編譯器會呼叫valueOf將原始型別值轉換成對象,同時自動拆箱時,編譯器透過呼叫類似intValue(),doubleValue() 這類的方法將物件轉換成原始型別值。

發生時間:

有一個方法,接受一個物件類型的參數,如果我們傳遞一個原始類型值,那麼 Java會自動講這個原始型別值轉換成對應的物件。

List<Integer> list = new ArrayList<Integer>();
// 自动装箱
list.add(1);
list.add(2);
// 拆箱
int i = list.get(0);
int ii = list.get(1);
登入後複製

自動裝箱的弊端:

自動裝箱有一個問題,那就是在一個循環中進行自動裝箱操作的情況,如下面的例子就會創造多餘的對象,影響程式的效能。

Integer sum = 0;
 for(int i=1000; i<5000; i++){
   sum+=i;
}
登入後複製

上面的程式碼sum+=i可以看成sum = sum + i,但是==##+-*/這個運算子不適用於Integer物件,首先sum進行自動拆箱操作,進行數值相加操作,最後發生自動裝箱操作轉換成Integer物件。其過程如下

int temp = sum.intValue() + i;
Integer sum = new Integer(temp);
登入後複製

由於我們這裡聲明的sumInteger##類型,在上面的循環中會創建將近5000個無用的Integer對象,在這樣龐大的循環中,會降低程式的效能並且加重了垃圾回收的工作量。因此,需要注意到這一點,正確地宣告變數類型,避免因為自動裝箱所引起的效能問題.

注意事項: #  

自動裝箱和拆箱可以讓程式碼簡潔,但是,我們在使用的時候應該要注意下,否則會發生一些問題。

1.比较

”==“可以用于原始值进行比较,也可以用于对象进行比较,当用于对象与对象之间比较时,比较的不是对象代表的值,而是检查两个对象是否是同一对象,即检查引用地址是否相同。这个比较过程中没有自动装箱发生。进行对象值比较不应该使用”==“,而应该使用对象对应的equals方法

// 1
int i1=1;
int i2=1;
System.out.println(i2==i1);// true
// 2
Integer I1=1;
System.out.println(I1==i1);// true
Integer I2=1;
System.out.println(I1==I2);// true
// 3
Integer I3 = 128;// 触发自动封装
Integer I4 = 128;
System.out.println(I3==I4);// false
// 4
Integer I5= new Integer(1);// 不触发自动封装
Integer I6= new Integer(1);
System.out.println(I5==I6); // false
登入後複製

值得注意的是第2个小例子的第二个比较,这是一种极端情况。I1和I2的初始化都发生了自动装箱操作。但是处于节省内存的考虑,JVM会缓存-128到127的Integer对象。因为I1和I2实际上是同一个对象。所以使用”==“比较返回true,而第三个小例子使用‘==’返回false

注:自动封装的函数

public static Integer valueOf(int i) {
 return i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
 }
private static final Integer[] SMALL_VALUES = new Integer[256];
登入後複製

2.容易混乱的对象和原始数据值

另一个需要避免的问题就是混乱使用对象和原始数据值,一个具体的例子就是当我们在一个原始数据值与一个对象进行比较或赋值时,如果这个对象没有进行初始化或者为Null,在自动拆箱过程中obj.xxxValue,会抛出NullPointerException,如下面的代码

private static Integer count;
if(count>=0){
System.out.println(11111111111L);
}
登入後複製

3.缓存的对象

Java中,会对-128到127的Integer对象进行缓存,当创建新的Integer对象时,如果符合这个这个范围,并且已有存在的相同值的对象,则返回这个对象,否则创建新的Integer对象。

4.生成无用对象

因为自动装箱会隐式地创建对象,像前面提到的那样,如果在一个循环体中,会创建无用的中间对象,这样会增加GC压力,拉低程序的性能。所以在写循环时一定要注意代码,避免引入不必要的自动装箱操作。

以上是談談Java資料型別中自動封裝拆箱與實例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!