2012-01-07 85 views
1

我遇到问题让这种类型转换正常工作。我的猜测是有界的通用通配符<? 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>> 

回答

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第二类型参数的(换言之该类型必须有一些实施IFace<T>)。

由于natix's answer points out,使用通配符泛型返回类型不鼓励,因为它有效地隐藏一部分返回的对象泛型类型的信息。取而代之的是,使该方法一般:

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

允许调用代码指定的X贯通式inferrence类型。

+0

你是对的,谢谢。几分钟后,我会删除我的答案。 – 2012-01-07 19:49:05

4

援引约书亚Bloch的Effective Java第二版:

不要使用通配符类型作为返回类型。它会强制用户在客户端代码中使用 通配符类型,而不是为用户提供额外的灵活性。

对于 类的用户来说,正确使用通配符类型几乎是不可见的。他们使方法接受他们应该接受的参数 并拒绝他们应该拒绝的参数。 如果一个班级的用户必须考虑通配符类型 ,那么012xx类的API可能有问题。

1

当您开始使用泛型时,真正的必读内容是this tutorial。如果您阅读第4页上的'泛型和子类型'部分,您将会知道为什么会出现该错误。它无关的事实你正在使用的接口

+1

教程链接似乎被打破。以下是类似信息的链接:http://docs.oracle.com/javase/tutorial/java/generics/index.html – SteveT 2012-11-06 15:00:19