4 に答える
リンゴは果物ですが、リンゴのリストは果物のリストではありません。
もしそうなら、あなたはリンゴのリストにバナナを入れることができます
リストを直接キャストすると、Java型システムが破壊されるため、問題が発生します。キャストは常に成功しますが、後でアイテムを取得しようとするとプログラムが失敗する可能性がありClassCastException
、その時点でエラーの原因が不明になる可能性があります。
一般に、プログラムはエラーの原因のできるだけ近くで失敗するようにします。リストをキャストすると、誰かが実際に要素にアクセスしようとする前にしばらくの間渡される可能性があり、リストがスローされるまでに、そのキャストまで追跡するのは非常に難しい場合ClassCastException
があります(少なくともプログラムはキャストで失敗しました)。
listA
あなたのコメントから、あなたはすべてが実際にあると確信しているようです。B
その場合、私はお勧めします:
List<B> listB = new ArrayList(listA.size());
for (A a : listA) {
if (a == null || a instanceof B) {
listB.add((B) a);
} else {
//Either ignore or throw exception
}
}
これを理解するList<A>
には、とが階層的に関連している場合でも、とは階層的に関連List<B>
していない2つの異なるタイプであることを理解する必要があります。のサブクラスであったとしても、aをaにキャストすると、そのリストにインスタンスを追加できる可能性があり(ただし、ではない)、コンパイラは実際の(実行時)と一致しなくても、喜んでそれを実行します。コレクションのタイプ。A
B
B
A
List<B>
List<A>
A
B
Javaでこれを回避できることを知りませんでしたが、型消去のみが原因である可能性があります。Javaは、などの1つのクラスを作成しList<Object>
、そのジェネリッククラスのさまざまな「実装」に対して、コードにキャストを追加するだけです。コンパイルする前に。これは、List<T>
オンデマンドで具体的な型を作成するために、実際には「コンパイルされた」テンプレート(「一般的な定義」と呼ばれる)としてのみ使用する(たとえば)C#とは対照的です。
ジェネリックスの動作は少し異なるため、BはAの型ですが、 list<B>はlist<A>型ではありません。