3

インターフェースは次のとおりです。

public interface Foo<T> extends Comparable<Foo<T>>  {
   ...
}

そして、このインターフェースを実装するいくつかのクラスがあります:

public class Bar extends Something implements Foo<Something> {
    public Vector<Foo<Bar>> giveBar() {
        ...
    }
}

public class Boo extends SomethingElse implements Foo<SomethingElse> {
    public Vector<Foo<Boo>> giveBoo() {
        ...
    }
}

ここで、ベクター内に多数の Foo (実際には Foo または Boos である可能性があります) を保持したいと考えています。

Bar bar = new Bar();
Boo boo = new Boo();
Vector<Foo<?>> vector;
if (...) 
   vector = bar.giveBar();
else
   vector = boo.giveBoo();

私は得る:

Type mismatch: cannot convert from Vector<Foo<SomethingElse>> to Vector<Foo<?>>

同じことが言えます:

Vector<Foo> vector;
if (...) 
   vector = giveBar();
else
   vector = giveBoo();

Bar と Boo の両方がこの問題の唯一の解決策を拡張するスーパークラスですか?

4

2 に答える 2

6

そのコードの要約は次のとおりです。

Vector<A> vector = new Vector<B>();

この場合、B は A を拡張しますが、型が一致しないため許可されません。これが機能しない理由を明確にするために、次のコードを想像してください。

Vector<Vector<?>> vector = new Vector<Vector<String>>();
vector.add(new Vector<Integer>());

変数の型は、未知の型のベクトルのベクトルです。それに割り当てられているのは、文字列のベクトルのベクトルです2 行目はそれに整数のベクトルを追加します。Vector<?>受け入れる変数のコンポーネントタイプVector<Integer>。しかし、実際のベクトルのコンポーネント タイプはVector<String>であり、そうではありません。コンパイラが最初の行の代入に異議を唱えなかった場合、発見されることなく間違った 2 行目を書くことができます。

C# のジェネリックにも同様の制限がありますが、違いは、C# のジェネリック クラスはコンポーネント タイプを格納するのに対し、Java はコードのコンパイル時にコンポーネント タイプを忘れることです。

ps - 一体なぜorVectorではなく使用しているのですLinkedListArrayList? スレッドの問題が関係しているためですか?

于 2008-11-03T13:31:02.397 に答える
2

使用できます

Vector<? extends Foo<?>> vector;
于 2008-11-03T13:36:49.000 に答える