List<SubClass>
を として扱いたい があります。を にList<BaseClass>
キャストするのは簡単なので問題ないように思えますが、コンパイラはキャストが不可能であるとエラーを出します。SubClass
BaseClass
では、 と同じオブジェクトへの参照を取得する最善の方法は何でしょうかList<BaseClass>
?
今は、新しいリストを作成し、古いリストをコピーしているところです。
List<BaseClass> convertedList = new ArrayList<BaseClass>(listOfSubClass)
しかし、私の理解では、完全に新しいリストを作成する必要があります。可能であれば、元のリストへの参照を希望します。
ベストアンサー1
この種の割り当ての構文ではワイルドカードを使用します。
List<SubClass> subs = ...;
List<? extends BaseClass> bases = subs;
重要なのはList<SubClass>
、ないは と交換可能ですList<BaseClass>
。 への参照を保持するコードは、List<SubClass>
リスト内のすべての項目が であると想定しますSubClass
。コードの別の部分でリストを として参照した場合、または が挿入されList<BaseClass>
てもコンパイラはエラーを出力しません。ただし、これにより、リスト内のすべての項目が であると想定される最初のコード部分でが発生します。BaseClass
AnotherSubClass
ClassCastException
SubClass
ジェネリック コレクションは、Java の配列と同じようには動作しません。配列は共変です。つまり、次のことが可能です。
SubClass[] subs = ...;
BaseClass[] bases = subs;
これは、配列がその要素の型を「知っている」ため許可されます。SubClass
配列のインスタンスではないものを (参照bases
経由で) 格納しようとすると、実行時例外がスローされます。
ジェネリックコレクションはないコンポーネントの型を「認識」しますが、この情報はコンパイル時に「消去」されます。したがって、無効なストアが発生しても実行時例外は発生しません。代わりに、ClassCastException
コレクションから値が読み取られるときに、コード内の遠く離れた、関連付けが難しいポイントで例外が発生します。型の安全性に関するコンパイラの警告に注意すれば、実行時にこれらの型エラーを回避できます。