<? extends Object>
和<E extends Object>
之间有什么区别?
应该何时使用另一个?
答案 0 :(得分:15)
以下是我立即想到的一些差异:
类型参数边界可以指定多个边界 - T extends A & B
,但使用通配符时,您无法指定多个边界 - ? extends A & B
无效。
您可以使用通配符设置下限 - ? super A
有效,但不能使用类型参数 - T super A
无效。
创建泛型类型时,不能使用通配符边界。您必须使用类型参数边界。
在方法内部,如果要在传递的参数的类型参数之间建立某种关系,则必须使用类型参数边界。例如,您希望传递具有相同类型参数的两个参数化类型。你不能用通配符边界做到这一点。因此,以下方法声明将采用两个相同类型参数的列表,即Number
。
public <T extends Number> void merge(List<T> list1, List<T> list2) {
}
最后,我将从 Effective Java中添加一些要点 - 第28项:使用有界通配符来提高API灵活性:
为获得最大的灵活性,请在表示生产者或使用者的输入参数上使用通配符类型。如果输入参数既是生产者又是消费者,那么通配符类型对您没有好处:您需要一个精确的类型匹配,这是您在没有任何通配符的情况下获得的。
不要将通配符类型用作返回类型。它不会为您的用户提供额外的灵活性,而是迫使他们在客户端代码中使用通配符类型。正确使用的通配符类型对于类的用户几乎是不可见的。它们使方法接受它们应该接受的参数并拒绝它们应该拒绝的参数。 如果一个类的用户必须考虑通配符类型,那么该类的API可能有问题。
<强>参考文献:强>
答案 1 :(得分:4)
<? extends Object>
是有界通配符(未知的扩展名为Object
,而<E extends Object>
属于有界类型(E
需要参数化类型扩展Object
)。
来自参数化上限的有界通配符的最微妙差异:
创建通用类型类时不能使用有界通配符,只允许输入类型参数。
有限通配符不能在Collection
中使用,它需要在集合中添加项目,因为它是未知类型,并且集合不知道它接收的是什么类型,因此它不是类型安全的。
有界通配符不能限制为多个泛型类型(边界)。
我希望这会有所帮助。
答案 2 :(得分:3)
如果您需要稍后参考该类型,请使用E
。如果您不必再次参考该类型,请使用?
。
答案 3 :(得分:0)
在通用代码中,称为通配符的问号(?)表示未知类型。通配符可用于各种情况:作为参数,字段或局部变量的类型;有时作为返回类型(虽然更好的编程实践更具体)。通配符从不用作泛型方法调用,泛型类实例创建或超类型的类型参数。有关详情,请查看this
答案 4 :(得分:-1)
<E>
声明一个类型参数
您只能在创建泛型类型或方法时使用它。
<? ...>
是类型参数的通配符值
您只能在创建封闭的泛型类型时使用它。