java generic array how simulate generic arrays java
このチュートリアルでは、オブジェクト配列を使用し、簡単な例でリフレクションクラスを使用して、Javaでジェネリック配列の機能をシミュレートする方法について説明します。
すでに議論しました Javaジェネリック 以前のチュートリアルの1つで。 Javaでは、型に関係なく宣言できるジェネリッククラスやメソッドなどを使用できます。 ただし、Javaでは配列を汎用にすることはできません。
これは、Javaでは、配列にコンポーネントに関連する情報が含まれており、この情報が実行時にメモリを割り当てるために使用されるためです。ジェネリックを使用する場合、型消去のため、バイトコードにはジェネリック情報が含まれていません。
=> ゼロからJavaを学ぶには、ここにアクセスしてください。
学習内容:
Javaのジェネリック配列
ジェネリック配列を定義した場合、コンポーネントタイプは実行時に認識されません。したがって、Javaで配列をジェネリックとして定義することはお勧めできません。
ジェネリック配列の定義は次のとおりです。
E () newArray = new E(length);
型情報は実行時に利用できないため、コンパイラはインスタンス化される正確な型を認識していません。
したがって、配列の代わりに、ジェネリックスが必要な場合は常に、Javaコレクションフレームワークのリストコンポーネントを優先する必要があります。ただし、Javaのオブジェクト配列とリフレクション機能を使用して、配列のような汎用構造を作成できます。
異なるデータ型の配列を定義できるようにするこれらの2つのアプローチについて、以下で詳しく説明します。
YouTubeのビデオをダウンロードするのに最適なサイト
ジェネリック配列を作成して初期化する
このセクションでは、本質的に一般的な配列のような構造を作成しましょう。これらの構造体を使用すると、データ型を引数として指定して配列を作成できます。
オブジェクト配列の使用
このアプローチでは、Objects型の配列をメイン配列クラスのメンバーとして使用します。また、get / setメソッドを使用して、配列要素を読み取って設定します。次に、必要に応じてデータ型を提供できるようにするメイン配列クラスをインスタンス化します。
これは、ジェネリック配列をシミュレートします。
次のプログラムは、オブジェクト配列を使用してジェネリック配列のような構造を作成する方法を示しています。
import java.util.Arrays; class Array { private final Object() obj_array; //object array public final int length; // class constructor public Array(int length) { // instantiate a new Object array of specified length obj_array = new Object (length); this.length = length; } // get obj_array(i) E get(int i) { @SuppressWarnings('unchecked') final E e = (E)obj_array(i); return e; } // set e at obj_array(i) void set(int i, E e) { obj_array(i) = e; } @Override public String toString() { return Arrays.toString(obj_array); } } class Main { public static void main(String() args){ final int length = 5; // creating integer array Arrayint_Array = new Array(length); System.out.print('Generic Array :' + ' '); for (int i = 0; i 出力:

C ++で書かれたソフトウェア
上記のプログラムでは、汎用のクラスArrayを定義しました。オブジェクト配列は、コンストラクターと長さを使用してインスタンス化されるクラスのメンバーです。また、特定のタイプの配列要素を読み取って設定するために使用される汎用のgetメソッドとsetメソッドも使用します。
次に、この配列クラスのインスタンスを作成します。インスタンスの作成中に、目的のタイプを指定できます。上記のプログラムでは、整数型と文字列型の2つの配列を作成し、これらの配列に適切な値を入力します(setメソッドを使用)。
最後に、オーバーライドされた「toString」メソッドを使用して、これらの各インスタンスのコンテンツを表示します。
リフレクションの使用
このアプローチでは、リフレクションクラスを使用して、実行時にのみ型が認識されるジェネリック配列を作成します。
このアプローチは前のアプローチと似ていますが、違いが1つだけあります。つまり、コンストラクター自体でリフレクションクラスを使用して、データ型情報をクラスコンストラクターに明示的に渡すことでオブジェクト配列をインスタンス化します。
このタイプの情報は、リフレクションのArray.newInstanceメソッドに渡されます。
次のプログラム ジェネリック配列を作成するためのリフレクションの使用法を示しています 。プログラム全体の構造は前のアプローチと似ていますが、リフレクション機能の使用法が異なるだけであることに注意してください。
importjava.util.Arrays; class Array { private final E() objArray; public final int length; // class constructor public Array(ClassdataType, int length){ // create a new array with the specified data type and length at runtime using reflection this.objArray = (E()) java.lang.reflect.Array.newInstance(dataType, length); this.length = length; } // get element at objArray(i) Eget(int i) { returnobjArray(i); } // assign e to objArray(i) void set(int i, E e) { objArray(i) = e; } @Override public String toString() { return Arrays.toString(objArray); } } class Main { public static void main(String() args){ final int length = 5; // create array with Integer as data type Arrayint_Array = new Array(Integer.class, length); System.out.print('Generic Array:' + ' '); for (int i = 0; i 出力:

上記のプログラムは、Arraysジェネリッククラスから作成された整数と文字列の2つのタイプの配列を示しています。
ジェネリックアレイ作成エラー
Javaでジェネリック配列を作成することの意味と、Javaでジェネリック配列を作成できない理由についてはすでに説明しました。これに対する別の説明は、Javaの配列は共変であるのに対し、ジェネリックはそうではないということです。ジェネリックは不変です。
共分散とは、サブタイプの配列をそのスーパータイプ参照に割り当てることができることを意味します。
これは、次のステートメントが正常に機能することを意味します。
Number numArray() = new Integer(10);
IntegerはNumberのサブタイプであるため、上記のステートメントは正常にコンパイルされます。
しかし、ジェネリックで同じ概念を使用する場合、それは機能しません。つまり、ジェネリックでは、サブタイプジェネリックをスーパータイプジェネリックに割り当てることはできません。
ステートメント、ListobjList = new ArrayList();ジェネリックは配列のように共変ではないため、コンパイルエラーが発生します。
上記の理由を念頭に置いて、私たちも以下のようなものを持つことはできません:
public static ArrayList() myarray = new ArrayList(2);
このステートメントは、エラーでコンパイルに失敗します。 「ジェネリックアレイの作成」 特定のジェネリック型への参照の配列を宣言できないためです。
ただし、ワイルドカードを使用して、特定の汎用タイプへの参照の配列を作成できます。上記のステートメントは、以下に示すようにワイルドカードを使用することを少し変更するだけで正常にコンパイルできます。
public static ArrayListmyarray = new ArrayList(5);
上記のステートメントは正常にコンパイルされます。
次のプログラムは、ワイルドカードの使用のデモンストレーションを示しています。
加重グラフ隣接リストc ++
import java.util.*; //generic array class classArr { T tarray(); Arr(T myarray()) { tarray = myarray; } @Override public String toString() { return Arrays.toString(tarray); } } public class Main { public static void main(String() args) { // Arrtarray() = new Arr(5); //error: generic array creation //initialize new array objects Arr arr1 = new Arr(new Integer(){2,4,6,8,10}); System.out.print('Array with Integer type:' + ' '); System.out.println(arr1); Arr arr2 = new Arr(new String(){'aa', 'bb', 'cc', 'dd'}); System.out.print('Array with String type:' + ' '); System.out.println(arr2); //define array objects using wildcard Arrarr3() = new Arr(5); arr3(0) = new Arr(new Integer(){10, 20, 30, 40, 50}); System.out.println('Integer array: ' + arr3(0)); arr3(1) = new Arr(new Float(){1.1f, 2.2f, 3.3f, 4.4f, 5.5f}); System.out.println('Float array: ' + arr3(1)); } }
出力:

上記のプログラムでは、ジェネリックスの不変性を示すmainメソッドの最初のステートメントがあります。このステートメントは、コンパイルエラー(コメントに表示)をフラッシュします。次の配列の作成はジェネリックスのルールに従って行われるため、正常にコンパイルされます。
よくある質問
Q#1)ジェネリックアレイとは何ですか?
回答: データ型に依存せず、実行時に情報の型が評価される配列は、ジェネリック配列です。ジェネリックはC ++のテンプレートに似ています。
Q#2)Javaでジェネリック配列を作成できますか?
回答: 配列はJavaでは共変です。つまり、任意のサブクラス配列をスーパータイプ配列に割り当てることができます。ただし、ジェネリックスは不変です。つまり、サブクラス型の配列をスーパークラス型に割り当てることはできません。
次に、ジェネリック情報がJVMから削除されるため、実行時にメモリ割り当てが行われる配列は、どのタイプが配列に割り当てられるかを認識しません。したがって、配列とジェネリックはJavaではうまく連携しません。
Q#3)JavaのタイプEとは何ですか?
回答: ジェネリックスのプレースホルダーとして機能し、あらゆるタイプの要素を表します。
Q#4)Javaの型消去とは何ですか?
回答: ジェネリックスで使用されるパラメーター化された型が削除され、バイトコードのraw型にマップされるJavaコンパイラーによって実行されるプロセス。そのため、バイトコードにはジェネリックに関する情報は含まれていません。
Q#5)JavaのRaw型とは何ですか?
回答: 生の型は、typeパラメーターを使用しないジェネリック型です。 例えば。 リストは生のタイプです。一方、Listはパラメーター化された型です。
結論
Javaでは、ジェネリック配列を直接定義することはできません。つまり、パラメータ化された型を配列参照に割り当てることはできません。ただし、オブジェクト配列とリフレクション機能を使用すると、一般的な配列の作成をシミュレートできます。
このチュートリアルでは、これら2つのアプローチを、一般的なアレイ作成エラーの詳細とそのようなエラーを防ぐ可能性とともに見てきました。一言で言えば、Javaでは、配列は共変であり、ジェネリックは不変であるため、配列とジェネリックは密接に関連していないと言えます。
=> ここで完璧なJavaトレーニングガイドをチェックしてください。
推奨読書