オートボクシングは、Javaコンパイラがプリミティブ型とそれに対応するオブジェクトラッパークラス間で行う自動変換です。たとえば、intからIntegerへの変換、doubleからDoubleへの変換など。変換が逆の場合、これはボックス化解除と呼ばれます。
なぜそれが必要なのか、なぜJavaでオートボクシングとアンボクシングを使用するのか?
オートボクシングはusedプリミティブデータ型をラッパークラスオブジェクトに変換します。ラッパークラスは、プリミティブ型で実行される幅広い機能を提供します。最も一般的な例は次のとおりです。
int a = 56;
Integer i = a; // Auto Boxing
それは、neededです。プログラマーが直接コードを簡単に記述でき、JVMが処理するためです。ボクシングとアンボクシング。
オートボクシングは、Java.util.Collection型を操作するときにも役立ちます。プリミティブ型のコレクションを作成する場合、プリミティブ型のコレクションを直接作成することはできませんが、オブジェクトのみのコレクションを作成できます。例えば :
ArrayList<int> al = new ArrayList<int>(); // not supported
ArrayList<Integer> al = new ArrayList<Integer>(); // supported
al.add(45); //auto Boxing
ラッパークラス
Javaの8つのプリミティブ型(byte、short、int、float、char、double、boolean、long)はそれぞれ、それらに関連付けられた別個のWrapperクラスを持っています。これらのWrapperクラスには、プリミティブデータ型で有用な操作を実行するためのメソッドが事前に定義されています。
Wrapper Classesの使用
String s = "45";
int a = Integer.parseInt(s); // sets the value of a to 45.
Wrapperクラスが提供する多くの便利な機能があります。 Java docs here をご覧ください
Unboxingは、ラッパークラスオブジェクトをプリミティブ型に戻す自動ボクシングの反対です。これはJVMによって自動的に行われるため、特定の操作にラッパークラスを使用し、プリミティブが処理を高速化するため、それらをプリミティブタイプに変換し直すことができます。例えば :
Integer s = 45;
int a = s; auto UnBoxing;
オブジェクトを操作するコレクションの場合、自動ボックス化解除のみが使用されます。方法は次のとおりです。
ArrayList<Integer> al = new ArrayList<Integer>();
al.add(45);
int a = al.get(0); // returns the object of Integer . Automatically Unboxed .
JDK 5以降、Javaには2つの重要な機能が追加されました。オートボクシングとオートアンボクシングです。 AutoBoxingは、そのようなオブジェクトが必要な場合にプリミティブ型が同等のラッパーに自動的にカプセル化されるプロセスです。オブジェクトを明示的に構築する必要はありません。 自動ボックス化解除は、カプセル化されたオブジェクトの値が、その値が必要なときに型ラッパーから自動的に抽出されるプロセスです。 intValue()やdoubleValue()などのメソッドを呼び出す必要はありません。
自動ボックス化と自動ボックス化解除の大幅な追加アルゴリズムの記述を簡素化、値の手動ボックス化とボックス化解除を排除します。 間違いを避けるにも役立ちます。また、非常に重要ですジェネリックの場合、オブジェクトのみを操作します。最後に、オートボクシングはCollections Frameworkでの作業を容易にします。
プリミティブ(非オブジェクト)タイプには効率性の正当化があります。
プリミティブ型int, boolean, double
は即時データであり、Object
sは参照です。したがって、フィールド(または変数)
int i;
double x;
Object s;
ローカルメモリ4 + 8 + 8が必要ですか?オブジェクトの場合、メモリへの参照(アドレス)のみが保存されます。
オブジェクトラッパーInteger, Double
などを使用すると、ヒープメモリ内のInteger/Doubleインスタンスへの参照、つまり間接参照が導入されます。
なぜボクシングが必要なのですか?
それは相対的な範囲の問題です。将来、JavaでArrayList<int>
を持ち、プリミティブ型を持ち上げることができるようになる予定です。
Answer:今のところ、ArrayListはObjectに対してのみ機能し、オブジェクト参照のためのスペースを確保し、同様にガベージコレクションを管理します。したがって、汎用型はオブジェクトの子です。したがって、浮動小数点値のArrayListが必要な場合は、Doubleオブジェクトでdoubleをラップする必要があります。
ここで、Javaは、テンプレートが従来のC++と異なります。C++クラスvector<string>, vector<int>
は、2つのコンパイル製品を作成します。 Java設計では、ArrayList.classが1つ必要でしたが、すべてのパラメータータイプに新しいコンパイル済み製品が必要ではありませんでした。
そのため、Objectにボクシングせずに、パラメータタイプが出現するたびにクラスをコンパイルする必要があります。具体的には、すべてのコレクションまたはコンテナクラスには、Object、int、double、booleanのバージョンが必要です。 Objectのバージョンは、すべての子クラスを処理します。
実際、int、char、doubleで動作するIntBuffer、CharBuffer、DoubleBuffer、...のJava SEには、そのような多様化の必要性が既に存在していました。一般的なソースからこれらのソースを生成することで、ハッキーな方法で解決されました。
(なぜ)ボクシングがあるのか
プリミティブとオブジェクト指向(OO)の代替を混在させるコードの記述をより快適/冗長にします。
なぜプリミティブとそのOO選択肢があるのですか?
プリミティブ型は(C#とは異なり)クラスではないため、Object
のサブクラスではないため、オーバーライドできません。
パフォーマンス上の理由でint
のようなプリミティブがあり、OOプログラミングの利点のためにObject
のようなInteger
の代替物があります。ユーティリティ定数とメソッドの場所(Integer.MAX_VALUEおよびInteger.toString(int)
)。
OOの利点は、ジェネリック(List<Integer>
)を使用すると最も簡単に表示されますが、それに限定されません。たとえば、次のとおりです。
Number getMeSome(boolean wantInt) {
if (wantInt) {
return Integer.MAX_VALUE;
} else {
return Long.MAX_VALUE;
}
}
オートボクシング:プリミティブ値を対応するラッパークラスのオブジェクトに変換します。
ボックス化解除:ラッパー型のオブジェクトを対応するプリミティブ値に変換する
// Java program to illustrate the concept
// of Autoboxing and Unboxing
import Java.io.*;
class GFG
{
public static void main (String[] args)
{
// creating an Integer Object
// with value 10.
Integer i = new Integer(10);
// unboxing the Object
int i1 = i;
System.out.println("Value of i: " + i);
System.out.println("Value of i1: " + i1);
//Autoboxing of char
Character gfg = 'a';
// Auto-unboxing of Character
char ch = gfg;
System.out.println("Value of ch: " + ch);
System.out.println("Value of gfg: " + gfg);
}
}
ArrayListは、クラスのみをサポートするプリミティブ型をサポートしません。しかし、int、doubleなどのプリミティブ型を使用する必要があります.
ArrayList<String> strArrayList = new ArrayList<String>(); // is accepted.
ArrayList<int> intArrayList = new ArrayList<int>(); // not accepted.
Integerクラスは、プリミティブ型intの値をobject.soにラップするため、以下のコードが受け入れられます。
ArrayList<Integer> intArrayList = new ArrayList<Integer>(); // is accepted.
add(value)メソッドで値を追加できます。文字列値を追加するには、strArrayListコードで「Hello」と言うだけで
strArrayList.add("Hello");
そして、私たちが書くことができる54というint値を追加します
intArrayList.add(54);
しかし、intArrayList.add(54);コンパイラは次の行に変換します
intArrayList.add(Integer.valueOf(54));
IntArrayList.add(54)はユーザー側から簡単で受け入れやすいため、コンパイラは `intArrayList.add(Integer.valueOf(54));
であるハードジョブを実行します。これはオートボクシングです。
同様に、値を取得するには、intArrayList.get(0)と入力し、コンパイラーは<code>intArrayList.get(0).intValue();
(autoUnboxing)に変換します。
なぜならそれらは異なるタイプであり、便利だからです。パフォーマンスがプリミティブ型を持つ理由である可能性があります。
一部のデータ構造はオブジェクトのみを受け入れ、プリミティブ型は受け入れません。
例:HashMapのキー。
詳細については、この質問を参照してください: HashMap and int as key
データベース内の「int」フィールドなど、他にも適切な理由がありますが、これもNULLになる可能性があります。 Javaのintはnullにできません。整数参照ができます。オートボックス化とアンボックス化には、変換での外部コードのやり取りを回避する機能があります。