简体   繁体   English

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

[英]Type mismatch with bounded wildcard ? super Type

I'm having a problem getting this type conversion working correctly. 我在使此类型转换正常工作时遇到问题。 My guess is the bounded generic wildcard <? 我的猜测是有界通用通配符<? super SomeType> doesn't work with interface implementations. 超级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>>

Citing Joshua Bloch's Effective Java 2nd Edition: 引用约书亚·布洛赫的有效Java第二版:

Do not use wildcard types as return types . 不要将通配符类型用作返回类型 Rather than providing additional flexibility for your users, it would force them to use wildcard types in client code. 与其为用户提供额外的灵活性,不如迫使用户在客户端代码中使用通配符类型。

Properly used, wildcard types are nearly invisible to users of a class. 正确使用的通配符类型对于类的用户几乎是不可见的。 They cause methods to accept the parameters they should accept and reject those they should reject. 它们使方法接受应接受的参数,并拒绝应接受的参数。 If the user of a class has to think about wildcard types, there is probably something wrong with the class's API . 如果类的用户必须考虑通配符类型,则类的API可能存在问题

When you start working with generics, a real must-read is this tutorial . 当您开始使用泛型时, 本教程是真正的必读内容。 If you read the 'Generics and Subtyping` section on page 4 you will know why you get that error. 如果您阅读第4页的“泛型和子类型化”部分,您将知道为什么会收到该错误。 It has nothing to do with the fact you are using an interface 这与您正在使用接口无关

Intuitively, one might try to resolve the issue by making the method generic: 直观地讲,可以尝试通过使方法通用来解决问题:

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

But this syntax isn't allowed, as it typically doesn't make sense to give a lower bound to type parameters using super . 但是这种语法是不允许的,因为使用super来给类型参数下界通常是没有意义的。 See this article for a good explanation of why: http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ107 请参阅本文,以获取有关原因的良好解释: http : //www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ107

Edit: 编辑:

Looking at your code, I think you may be confusing super with extends in specifying bounds of a type parameter. 看你的代码,我想你可能会产生混淆superextends在指定类型参数的边界。 It would be meaningful if getList() returned a List<MyClass<T, ? extends IFace<T>>> 如果getList()返回List<MyClass<T, ? extends IFace<T>>>是有意义的List<MyClass<T, ? extends IFace<T>>> List<MyClass<T, ? extends IFace<T>>> instead, as this is specifying an upper bound on the second type parameter of MyClass (in other words that type must be something implementing IFace<T> ). List<MyClass<T, ? extends IFace<T>>> ,因为这是在MyClass的第二个类型参数指定一个上限 (换句话说,该类型必须是实现IFace<T> )。

As natix's answer points out , using wildcards in generic return types is discouraged because it effectively hides part the generic type information for the returned object. 正如natix的答案所指出的那样 ,不建议在通用返回类型中使用通配符,因为它有效地隐藏了返回对象的通用类型信息。 Instead, make the method generic: 相反,使方法通用:

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

Which allows the calling code to specify the type of X through type inferrence. 它允许调用代码通过类型推断来指定X类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM