Java汎用(二)--汎用リストと配列


以前面接の時に質問されたことがあるのを覚えています.配列とリストの違いは何ですか.そのときの答えは,効率,容量固定,リストの基本タイプを保存できないことなどにほかならない.Javaが1.5に発展した後、汎用バージョンのリストが現れ、この問題の解答に追加された.この話題についてお話しします.
1.配列のコヒーレンス.
配列のコヒーレンス(covariant)とは、クラスBaseがクラスSubのベースクラスである場合、Base[]がSub[]のベースクラスであることを意味する.汎用型は可変であり(invariant)、ListはListのベースクラスではなく、そのサブクラスではない.配列のコヒーレンス性は、次のコードなどのエラーを引き起こす可能性があります.
Javaコード
	public static void main(String[] args) {
		Object[] array = new String[10];
		array[0] = 10;
	}

配列がコヒーレントであるため、Object[]タイプの参照はString[]タイプのオブジェクトを指すことができます.しかし、運行時には以下の異常が報告されます.
Exception in thread "main"java.lang.ArrayStoreException: java.lang.Integer
原因は呼吸のように簡単だ.
しかし、汎用型ではこのようなことは起こりません.
Javaコード
	public static void main(String[] args) {
		List<Object> list = new ArrayList<String>();
		list.add(10);
	}

このコードはコンパイルもできません.
2.配列の具体化.
2つ目の問題は、配列が具体化され(refied)、汎用型が実行時に消去されることである.配列は実行時に配列要素のタイプ制約を判断するが,汎用は正反対であり,実行時には汎用のタイプ情報が消去され,コンパイル時にのみタイプが強化される.
したがって、上記の例では、配列のメソッドはArrayStoreExceptionを実行するときにタイムズされ、汎用型はコンパイルできません.
3.汎用型と配列の結合.
この問題のタイトルは少し誤導的で,実際には汎用型と配列はまったく結合する可能性がない.List[]、List[]、またはE[]の書き方が間違っています.これらの方法では、タイプのセキュリティが提供されないためです.2つの例を挙げて、それらが引き起こすエラーを説明します.
Javaコード
	public void testMethod1() {
		List<Integer>[] array = new List<Integer>[10];
		List<String> list = new ArrayList<String>();
		Object[] objs = array;
		objs[0] = list;
	}

このコードは、arrayという汎用配列が作成可能であると仮定し、Object[]タイプの変数によって参照され、arrayの要素がListタイプになり、タイプエラーが発生します.
2つ目の例は、タイプパラメータ配列についてです.
Javaコード
	public <E> void testMethod2(E e) {
		E[] array = new E[10];
		Object[] objs = array;
		objs[0] = e;
		objs[1] = "string";
		objs[2] = 10;
		objs[2] = true;
	}

上の例と似ていて、arrayはどんなタイプの要素を入れることができます.これは安全ではありません.
ここで例外として,無制限ワイルドカード型の汎用は汎用配列を作成できるといえる.
Javaコード
List<?>[] listArray = new List<?>[10];