これは合法であるべきだと思いますが、コンパイラはこの点について私に同意しません
一般に、人間とコンパイラが意見を異にする場合、コンパイラの側につくのが安全です。コンパイラをだますのではなく、まず変換が許可されない理由を理解する必要があります。
これを考慮してください: 次のように を作成しますList<B>
。
List<B> listB = new ArrayList<B>();
これまでのところ、誰もが幸せです。今、あなたが正しいと思うことをしましょう:
// This does not compile, but let's pretend that it does
List<A> listA = (List<A>)listB;
この時点で、listA
それは完全に私たちのものです!遊んでみましょう: 別のクラスC
extendsがあるとしましょうA
。これはできますか?
listA.add(new C()); // Why not? The compiler should allow it!
でも待ってください、私たちが何をしたか分かりますか? 私たちlistB
には今が含まれていC
ます!これが、コンパイラが変換を許可しない理由です。これは、リストに何かを追加しようとした場合にコードが安全でない理由でもあります。
この問題を回避するには、ワイルドカードを使用できます: List<? extends A>
. ただし、これにより、リストへのアクセスが読み取り専用に制限されます。List
書き込みを許可する必要がある場合 (そして、適切なものだけを設定することがわかっている場合) は、代わりに非ジェネリックを使用してください。