ホームページ  >  記事  >  Java  >  Java データ型の自動カプセル化、アンボックス化、およびサンプル分析について説明します。

Java データ型の自動カプセル化、アンボックス化、およびサンプル分析について説明します。

零下一度
零下一度オリジナル
2017-06-23 10:04:211919ブラウズ

目的:

オートボックス化とアンボックス化はJava 1.5から導入され、オブジェクトのAPIを使用するためにプリミティブ型の値を対応するオブジェクトに自動的に変換することを目的としています。参照型の操作。自動ボックス化およびボックス化解除メカニズムにより、Java での変数割り当てまたはメソッド呼び出しでプリミティブ型またはオブジェクト型を使用することがより簡単かつ直接的になります。

定義:

オートボクシングは、int変数をIntegerオブジェクトに変換するなど、プリミティブ型の値を対応するオブジェクトに自動的に変換するJavaです。プロセスと呼ばれます逆に、Integerオブジェクトをint型の値に変換することをアンボックス化と呼びます。ここでのボックス化とアンボックス化は、人間による自動変換であるため、自動ボックス化とアンボックス化と呼ばれます。プリミティブ型byte、short、char、int、long、float、doubleおよびbooleanに対応するカプセル化クラスは、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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。