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>>
4

3 回答 3

4

引用 Joshua Bloch 的 Effective Java 2nd Edition:

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

如果使用得当,通配符类型对类的用户几乎是不可见的。它们使方法接受它们应该接受的参数并拒绝它们应该拒绝的参数。如果某个类的用户必须考虑通配符类型,则该类的 API 可能有问题

于 2012-01-07T19:31:06.660 回答
1

当您开始使用泛型时,真正的必读是本教程。如果您阅读第 4 页的“泛型和子类型化”部分,您就会知道为什么会出现该错误。它与您使用界面的事实无关

于 2012-01-07T19:31:35.207 回答
0

直觉上,人们可能会尝试通过使方法通用来解决这个问题:

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

但是这种语法是不允许的,因为使用super. 有关原因的详细说明,请参阅本文:http ://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ107

编辑:

查看您的代码,我认为您在指定类型参数的范围时super可能会感到困惑。extends如果返回 a是有意义的,因为这是指定第二个类型参数的上限(换句话说,该类型必须是实现的东西)。 getList()List<MyClass<T, ? extends IFace<T>>>MyClassIFace<T>

正如natix 的回答所指出的那样,不鼓励在泛型返回类型中使用通配符,因为它有效地隐藏了返回对象的泛型类型信息的一部分。相反,使方法通用:

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

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

于 2012-01-07T19:33:54.407 回答