Javaでは汎用配列を作成できないソリューション

3281 ワード

Javaでは汎用配列を作成できないソリューション
質問:
Javaでは「正確な汎用タイプの配列を作成できません」です.
つまり、次の例はできません.
List[] ls = new ArrayList[10];  

ワイルドカードを使用して汎用配列を作成することは、次の例のようにできます.
List>[] ls = new ArrayList>[10];  

これも可能です.
List[] ls = new ArrayList[10];

この問題をSunの文書の一例を用いて説明します.
List[] lsa = new List[10]; // Not really allowed.    
Object o = lsa;    
Object[] oa = (Object[]) o;    
List li = new ArrayList();    
li.add(new Integer(3));    
oa[1] = li; // Unsound, but passes run time store check    
String s = lsa[1].get(0); // Run-time error: ClassCastException.

この場合、JVM汎用型の消去メカニズムは、実行時にJVMが汎用情報を知らないため、oa[1]に異常が発生することなくArrayListを付与することができるが、データを取り出す際に一度タイプ変換を行うのでClassCastExceptionが発生し、汎用配列の宣言が可能であれば、上記の状況では、コンパイル中に警告やエラーは発生せず、実行時にのみエラーが発生します.
汎用配列の宣言を制限する場合、コンパイル中にプロンプトコードにタイプセキュリティの問題があり、プロンプトがないよりもずっと強いことができます.
ソリューション
1.ワイルドカードの解決策はIntegerとStringを入れることさえできます!!!
The Java™ Tutorials:Genericsが提供するソリューションは次のとおりです.
List>[] lsa = new List>[10];                //1
List li = new ArrayList();
li.add(new Integer(3));
// Correct.
lsa[1] = li;
// Run time error, but cast is explicit.
Integer s = (Integer) lsa[1].get(0);              //2

無限のワイルドカードを借りてもいいですか?未知のタイプを表すため、関連する操作は基本的にタイプとは無関係であるため、jvmはタイプを判断する必要がないため、コンパイルできますが、配列内の要素はワイルドカードのため、読むしかなく、書くことができません.たとえば、上のlsaというローカル変数はget()操作しかできず、add()操作はできません.操作タイプの場合、タイプの具体的な機能を使用する必要がない場合は、Objectクラスの機能のみを使用します.では、使えますか.ワイルドカードは未知のタイプを表します.しかしli変数によりadd()操作を行うことができる.
以上、配列のタイプは、ワイルドカードを使用しない限り、タイプ変数ではありません.ワイルドカードの場合、最後にデータを取り出すには明示的なタイプ変換が必要です.
2.反射反射の解決策は、最初に宣言した<>の内容しか配置できません!!!java.util.reflect.Arrayを使用すると、ワイルドカードを使用せずに汎用配列の効果を得ることができます.
   List[] lsa = (List[])Array.newInstance(ArrayList.class, 4);     //1
   Object o = lsa;
   Object[] oa = (Object[]) o;
   List li = new ArrayList();
   li.add("3");
   / Correct.
   oa[1] = li;
   // Run time error, but cast is explicit.
   String s = lsa[1].get(0);                                                       //2
   System.out.println(s);
Array.newInstance()を用いて汎用配列を生成したが,ここではワイルドカードは一切用いられず,2番目にも明示的なタイプ変換は行われなかったが,1番目には明示的なタイプ変換は依然として存在した.
3.3まとめ を使用するには、プログラマが表示されるタイプ変換を1回実行する必要があります.すなわち、タイプチェックの問題をコンパイラからプログラマに渡す必要があります.実際にJavaの設計者は、(List[])Array.newInstance(ArrayList.class, 4)unchecked warningがあり、コンパイラがプログラマーに注意している , , !です.