1

Java では、クラスのインスタンスを、拡張されたクラスBのインスタンスAにキャストできます。BA

これは、型パラメーター化されたクラスに対しても実行できますか? たとえば、 をB拡張Aするには、次のようにします。

List<A> l = new ArrayList<B>();

これは合法であるべきだと思いますが、コンパイラはこの点で私に同意しないので、次のハックでだましました:

List<A> l = (List<A>)(List) new ArrayList<B>();

……でも、ヴェロキラプトルにやられると思います。これを行うエレガントな方法はありますか?

4

4 に答える 4

3

これは合法であるべきだと思いますが、コンパイラはこの点について私に同意しません

一般に、人間とコンパイラが意見を異にする場合、コンパイラの側につくのが安全です。コンパイラをだますのではなく、まず変換が許可されない理由を理解する必要があります。

これを考慮してください: 次のように を作成します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それは完全に私たちのものです!遊んでみましょう: 別のクラスCextendsがあるとしましょうA。これはできますか?

listA.add(new C()); // Why not? The compiler should allow it!

でも待ってください、私たちが何をしたか分かりますか? 私たちlistBには今が含まれていCます!これが、コンパイラが変換を許可しない理由です。これは、リストに何かを追加しようとした場合にコードが安全でない理由でもあります。

この問題を回避するには、ワイルドカードを使用できます: List<? extends A>. ただし、これにより、リストへのアクセスが読み取り専用に制限されます。List書き込みを許可する必要がある場合 (そして、適切なものだけを設定することがわかっている場合) は、代わりに非ジェネリックを使用してください。

于 2012-10-27T12:19:25.823 に答える
2
List<? extends A> l = new ArrayList<B>();

ここでJavaのジェネリックについて読む必要があります

于 2012-10-27T12:13:14.047 に答える
0

やり方は二通り…………

-この処理方法Collectionsは行われます。原因Arrayコンパイル時と実行時にチェックされますCollections、チェックされるのは実行時のみCompile timeです。

-そのため、別のタイプのオブジェクトを別のタイプの Collection に誤って追加してはなりません。つまり、Dog オブジェクトを Cat コレクションに追加してはなりません。

1.

public <T extends A> void go(ArrayList<T> aList){


}

2.

public void go(ArrayList<? extends A> aList){


}
于 2012-10-27T12:22:05.283 に答える
0

非一般的なコンテキストでは、B が A である場合、B を A に置き換えることができますが、A を B に置き換えることはできません。

ジェネリックでは、List と List はどちらも "is a"Collection<E>です。つまり、List は List のサブクラスではないため、List を List に置き換えることはできません。

お探しのジェネリックに関する特定のコンテンツは、こちらで見つけることができます。便宜上、以下にコピーします。

2 つの具象型 A と B (Number と Integer など) が与えられた場合、A と B が関連しているかどうかに関係なく、MyClass は MyClass と何の関係もありません。MyClass と MyClass の共通の親は Object です。

于 2012-10-27T12:22:12.483 に答える