键入与有界通配符不匹配?超级型

时间:2012-01-07 19:19:37

标签: java generics bounded-wildcard

我在使此类型转换正常工作时遇到问题。我的猜测是有界通用通配符<? super SomeType>不适用于接口实现。

// sample class definitions
public interface IFace<T> { ... } 
public class MyClass<T1, T2> { ... }
public class UtilityClass<T> {
    public List<MyClass<T, ? super IFace<T>>> getList() { ... }
}
public class Actor extends SomeObj implements IFace<TypeA> { ... }

// use...
UtilityClass<TypeA> utility = new UtilityClass<TypeA>();
List<MyClass<TypeA, Actor>> list = utility.getList();

Type mismatch: cannot convert from List<MyClass<TypeA, ? super IFace<TypeA>> to List<MyClass<TypeA, Actor>>

3 个答案:

答案 0 :(得分:4)

引用Joshua Bloch的Effective Java第二版:

  

不要将通配符类型用作返回类型。而不是提供   为用户提供额外的灵活性,这将迫使他们使用   客户端代码中的通配符类型。

     

正确使用的通配符类型对于a的用户几乎是不可见的   类。它们使方法接受它们应该接受的参数   并拒绝他们应该拒绝的人。 如果班级的用户必须   想想通配符类型,可能有些问题   class的API

答案 1 :(得分:1)

当您开始使用泛型时,真正必读的是this tutorial。如果您阅读第4页的“泛型和子类型”部分,您将知道为什么会出现该错误。它与您使用接口

的事实无关

答案 2 :(得分:0)

直观地说,人们可能会尝试通过使方法通用来解决问题:

public <X super IFace<T>> List<MyClass<T, X> getList() { ... }

但是不允许使用此语法,因为使用super给出参数的下限通常没有意义。请参阅此文章,了解原因:http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ107

修改

查看代码,我认为在指定类型参数的边界时,superextends混淆。如果getList()返回List<MyClass<T, ? extends IFace<T>>>,则 会有意义,因为这会在MyClass的第二个类型参数上指定 upper (换句话说,该类型必须是实现IFace<T>)的东西。

作为natix's answer points out,不鼓励在泛型返回类型中使用通配符,因为它有效地隐藏了返回对象的泛型类型信息。相反,使方法通用:

public <X extends IFace<T>> List<MyClass<T, X> getList() { ... }

允许调用代码通过类型推断来指定X的类型。