Aは、大まかに言えばBのサブタイプある場合は、タイプBの変数にタイプAの何かを割り当てることができ、これは、AがBが行うすべての操作をサポートしなければならないことを意味します。
あなたの例を見て:
まず:
List<Object> objectList = new ArrayList<Integer>();//compile time error
右、ArrayList<Integer>
がList<Object>
ではありませんので。 Object
を追加することはできません。考えてみましょう:
List<Object> l = new ArrayList<Object>();
List<Integer> l2 = new ArrayList<Integer>();
l.add(new Object()); // ok
l2.add(new Object()); // not ok; `List<Integer>` doesn't support this.
ですからList<Integer>
(またはArrayList<Integer>
)を参照してくださいList<Object>
のサブタイプではありません - それはすべて同じ操作をサポートしていないため。
次へ:この場合
Object object = new Integer(9);
object = 1.2;// no run time error
、値1.2
ラッパータイプDouble
(フルネームjava.lang.Double
)に自動箱詰めです。これはObject
のサブクラスなので、割り当ては正常に動作します。変数object
に格納されるのは、プリミティブdouble
の値1.2ではなく、プリミティブ値をラップするDouble
オブジェクトへの参照です。最後に
:
Object objectArr[] = new Integer[1];
objectArr[0] = 1.2;// run time error (Exception in thread "main" java.lang.ArrayStoreException: java.lang.Double)
これは変わり者ケースです。 JavaはInteger
の配列をObject
の配列のサブタイプと見なしますが、通常の型理論ではそうではありませんが、Object
(これもInteger
ではありません)をこのような配列に格納することはできません。一方、Integer
の配列は、配列Object
の他のすべての操作をサポートしています。要素を取得し、サブタイプがObject
であることを確認できます。配列の長さをチェックすることができます。したがって(配列Integer
)をObject[]
の変数に割り当てることができます。
このタイプのサブタイプ作業を行うには、Integer
アレイは暗黙のうちにObject[]
と同様の「ストアObject
要素」操作を実装する必要があります。しかし、Integer[]
にはInteger
オブジェクトしか含まれていないため、ストア操作は失敗する必要があります。Integer
以外のものを保存しようとすると、実行時に例外が発生します。あなたの例では、Integer
ではなく、Double
に自動ボックス化された1.2
を保存しています。
最初の例のコンパイル時に発生するエラーは何ですか? –
これが正しい! *共分散*と創世記の反反動についての研究を行う。 – GhostCat