16

<? extends Object>和有什么区别<E extends Object>?什么时候应该使用一个而不是另一个?

4

5 回答 5

16

以下是我立即想到的一些差异:

  • 类型参数 bounds 可以指定多个边界 - T extends A & B,但使用通配符不能指定多个边界 -? extends A & B无效。

  • 您可以使用通配符设置下限 -? super A有效,但不使用类型参数 -T super A无效。

  • 创建泛型类型时不能使用通配符边界。您必须使用类型参数边界。

  • 在方法内部,如果您希望传递的参数的类型参数之间存在某种关系,那么您必须使用类型参数边界。例如,您想传递两个具有相同类型参数的参数化类型。你不能用通配符边界来做到这一点。因此,以下方法声明将采用两个相同类型参数的列表,即 extends Number

    public <T extends Number> void merge(List<T> list1, List<T> list2) {
    }
    

最后,我将添加来自Effective Java - Item 28: Use bounded wildcards to increase API灵活性的一些观点:

为了获得最大的灵活性,请在代表生产者或消费者的输入参数上使用通配符类型。如果输入参数既是生产者又是消费者,那么通配符类型对你没有好处:你需要一个精确的类型匹配,这就是你在没有任何通配符的情况下得到的。

不要使用通配符类型作为返回类型。它不会为您的用户提供额外的灵活性,而是会迫使他们在客户端代码中使用通配符类型。如果使用得当,通配符类型对类的用户几乎是不可见的。它们使方法接受它们应该接受的参数并拒绝它们应该拒绝的参数。如果某个类的用户必须考虑通配符类型,则该类的 API 可能有问题。


参考:

于 2013-08-22T15:42:45.273 回答
5

E如果您稍后需要引用类型,请使用。?如果您永远不必再次引用类型,请使用。

于 2013-08-22T15:34:52.523 回答
4

<? extends Object>是有界通配符(extends 的未知数Object,而 <E extends Object>类型是有界的(E需要 extends 的参数化类型Object)。

有界通配符与参数化上限的最细微差异:

  • 创建通用类型类时不能使用有界通配符,只允许使用类型参数。

  • 有界通配符不能用于Collection需要在集合中添加项目的 s 中,因为它是未知类型,并且集合不知道它正在接收什么类型,因此它不是类型安全的。

  • 有界通配符不能绑定到多个泛型类型(边界)。

我希望这有帮助。

于 2013-08-22T15:34:51.993 回答
0

在通用代码中,称为通配符的问号 (?) 表示未知类型。通配符可用于多种情况:作为参数、字段或局部变量的类型;有时作为返回类型(尽管更具体的是更好的编程实践)。通配符永远不会用作泛型方法调用、泛型类实例创建或超类型的类型参数。有关更多信息,请查看

于 2013-08-22T15:36:53.343 回答
-1

<E>声明一个类型参数。
您只能在创建泛型类型或方法时使用它。

<? ...>是类型参数的通配符
您只能在创建封闭的泛型类型时使用它。

于 2013-08-22T15:34:59.477 回答