【问题标题】:Type mismatch with generics类型与泛型不匹配
【发布时间】:2010-09-20 11:41:46
【问题描述】:

这是一个界面:

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() {
        ...
    }
}

现在我想在一个向量中保留一堆 Foos(可能真的是 Foos 或 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 都扩展的超类是解决这个问题的唯一方法吗?

【问题讨论】:

    标签: java generics types mismatch


    【解决方案1】:

    所有代码归结为:

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

    在这种情况下,B 扩展了 A,但这是不允许的,因为类型不匹配。为了弄清楚为什么这不起作用,想象一下下面的代码:

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

    变量的类型是一个未知类型向量的向量;并且分配给它的是一个字符串向量的向量。第二行添加了一个整数向量。变量Vector&lt;?&gt;的组件类型,接受Vector&lt;Integer&gt;;但实际向量的组件类型是Vector&lt;String&gt;,它不是。如果编译器不反对第一行的赋值,它将允许您编写不正确的第二行而不会被发现。

    C#的泛型也有类似的限制,不同的是C#中的泛型类存储它的组件类型,而Java在编译代码时会忘记组件类型。

    ps - 你到底为什么使用Vector 而不是LinkedListArrayList?是不是因为涉及到线程问题?

    【讨论】:

      【解决方案2】:

      你可以使用

      Vector<? extends Foo<?>> vector;
      

      【讨论】:

        猜你喜欢
        • 2015-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-18
        相关资源
        最近更新 更多