JAvaのコヒーレンス性の配列およびlistの解析.

1987 ワード

1、配列のコヒーレンス
配列のコヒーレンス(covariant)とは、
クラスBaseがクラスSubのベースクラスである場合、Base[]はSub[]のベースクラスである.
汎用型は可変であり、ListはListのベースクラスではなく、そのサブクラスではない.
配列のコヒーレンス性は、次のコードなどのエラーを引き起こす可能性があります.
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

しかし、汎用型ではこのようなことは起こりません.
public static void main(String[] args) { 
    List< Object> list = new ArrayList< String>(); 
    list.add(10); 
}

このコードはコンパイルもできません.
2、配列の具体化.
配列は具体化され(refied)、汎用型は実行時に消去される(erasure).
配列は実行時に配列要素のタイプ制約を判断し、
汎用型は正反対で、実行時に汎用型のタイプ情報が消去され、コンパイル時にのみタイプが強化されます.
したがって、上記の例では、配列のメソッドはArrayStoreExceptionを実行するときにタイムズされ、汎用型はコンパイルできません.
3、汎用型はコヒーレントではない
集合を配列の抽象と見なすのは役に立つが,配列には集合に備わっていない特殊な性質がある.
Java言語の配列はコヒーレント(covariant)である.つまり、IntegerがNumberを拡張した場合(事実もそうである)、IntegerがNumberであるだけでなく、Integer[]もNumber[]であり、Number[]を要求する場所でInteger[]を完全に伝達または付与することができる.(より正式には、NumberがIntegerのスーパータイプであれば、Number[]Integer[]のスーパータイプでもあります).
この原理は、一般的なタイプであるリストがリストのスーパータイプである場合にも適用されると思います.リストが必要な場所でリストを渡すことができます.残念なことに、状況はそうではありません.
それを許さないには十分な理由があります.
これにより、提供するタイプのセキュリティ汎用性が破壊されます.
リストをリストに割り当てることができれば.
次のコードでは、Integer以外のコンテンツをリストに入れることができます.
List li = new ArrayList();
List ln = li; // illegal
ln.add(new Float(3.1415));

lnはListであるため,Floatを追加することは完全に合法的であるようである.しかし、lnがliの別名である場合、これはli定義に含まれるタイプのセキュリティ承諾を破壊します.これは整数リストであり、汎用タイプがコヒーレントできない理由です.
リストで汎用を使用するには、2つの方法があります.1つは統一されたタイプです.
(List li = newArrayList();)
もう1つはワイルドカードを使用した行です
(List extends Number> li = newArrayList();)