<?>和<?有什么区别?在Java泛型中扩展Object>?


94

我已经看过以前用来表示任何对象的通配符-但最近看到了以下用法:

<? extends Object>

由于所有对象都扩展了对象,所以这两种用法是同义词吗?


2

3
@Dan如果您在该问题中搜索“?extends Object”,您将找不到任何东西。我正在阅读答案,以了解是否可以推断出任何内容,但我认为不是。具体来说,它不是在谈论泛型。
orbfish

@丹-这是一个不同的问题。我之前已经看过这个问题,并且至少记得提到过一个细微的区别。让我看看,如果我能找到它..
保罗Bellora

它也没有这一项,如果你找到它: stackoverflow.com/questions/678822/...
orbfish

1
我们来看看:Java无界通配符的可能重复项(同样有Kevin Bourrillion提供的错误答案。)
Paul Bellora 2011年

Answers:


103

<?>并且<? extends Object>是同义的,正如你所期望的。

在某些情况下,泛型extends Object实际上并不是多余的。例如,<T extends Object & Foo>将导致T成为Object下删除,而与<T extends Foo>它会成为Foo下删除。(如果您要保留与使用的前泛型API的兼容性,这可能很重要Object。)

来源:http : //download.oracle.com/javase/tutorial/extra/generics/convert.html ; 它解释了为什么JDK的java.util.Collections类具有带有此签名的方法:

public static <T extends Object & Comparable<? super T>> T max(
    Collection<? extends T> coll
)

4
我不清楚该示例如何与之相关?(因为它既不使用<?>也不使用<?
extended

27
@orbfish:它仅仅涉及在我以为你会发现它很有趣,因为它是其中一个例子extends Object实际上有意义的。如果我弄错了,那我道歉。希望至少其他人对您的问题感兴趣。
ruakh

@ruakh-对有界通配符而不是类型参数感兴趣,但至少您已回答。
orbfish 2011年

1
那您应该在原始帖子中这样说。这样,他的答案可能与您更相关。
liltitus13年

19

虽然<?>应该是的捷径<? extend object>,但两者之间的差别很小。 <?>是可辩护的,而<? extend object>不是。他们这样做的原因是为了更容易区分可确定类型。什么是像<? extends something><T><Integer>是nonreifiable。

例如,此代码将起作用

List aList = new ArrayList<>();
boolean instanceTest = aList instanceof List<?>;

但这给出了一个错误

List aList = new ArrayList<>();
boolean instancetest = aList instanceof List<? extends Object>;

有关更多信息,请阅读Maurice Naftalin的Java泛型和集合。


如果编译器将List <?>转换为List <Object>,那么如何保证它的可靠性?迷路了吗?
Trismegistos

我相信<?>更适合与旧版API向后兼容。区分<Object>和<?扩展了Object>,它们是Java 5后的代码。
丹尼斯·

9

<?>是的简写<? extends Object>。您可以阅读下面的共享链接以获取更多详细信息。


<?>

"?"表示任何未知类型,可以在代码中表示处的任何Type。如果不确定类型,请使用此通配符。

ArrayList<?> unknownList = new ArrayList<Number>(); //can accept of type Number
unknownList = new ArrayList<Float>(); //Float is of type Number

注意: <?>表示任何意思。因此它可以接受不是从Object类继承的Type 。

<? extends Object>

<? extends Object>意味着您可以传递对象或扩展Object类的子类。

ArrayList<? extends Number> numberList = new ArrayList<Number>(); //Number of subclass
numberList = new ArrayList<Integer>(); //Integer extends Number
numberList = new ArrayList<Float>(); // Float extends Number 

在此处输入图片说明

T –表示类型
E –表示元素
K –键
V –值
N –数字
Ref:

在此处输入图片说明


“因此它可以接受不是从Object类继承的Type”,但是所有Java类都是从Object该类继承或隐式继承的。
hackjutsu
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.