java 列表<?> vs 列表<? 扩展对象>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14346622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 15:57:09  来源:igfitidea点击:

List<?> vs List<? extends Object>

javagenerics

提问by Anton Kasianchuk

Possible Duplicate:
What's the difference between <?> and <? extends Object> in Java Generics?

可能的重复:
<?> 和 <? 在 Java 泛型中扩展 Object>?

I found that List<?>and List<? extends Object>act in the same way. As for me, there are no difference between them. If I am not right, can you explain me the difference?

我发现了这一点,List<?>List<? extends Object>以同样的方式行事。至于我,他们之间没有区别。如果我说得不对,你能解释一下区别吗?

import java.util.ArrayList;
import java.util.List;

public class TestClass {

static void func1(List<?> o, Object s) {
    o.add(null); // only null
    o.add(s); // wrong
    o.get(0);  // OK
}

static void func2(List<? extends Object> o, Object s) {
    o.add(null); // only null
    o.add(s); // wrong
    o.get(0); // OK
}

public static void main(String[] args) {
    func1(new ArrayList<String>(), new Integer(1));
    func2(new ArrayList<String>(), new Integer(1));

    List<? extends Object> list1 = new ArrayList<Object>();
    List<?> list2 = new ArrayList<Object>();

    List<? extends Object> list3 = new ArrayList<String>();
    List<?> list4 = new ArrayList<String>();
}
}

回答by irreputable

It is complicated...

这很复杂...

For any type variable T, the spec says http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4

对于任何类型变量T,规范说http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4

Every type variable ... has a bound. If no bound is declared for a type variable, Object is assumed.

每个类型变量……都有一个界限。如果没有为类型变量声明边界,则假定为 Object。

One would think that it's true for wildcard too, and ?should just be a shorthand for ? extends Object.

有人会认为通配符也是如此,?应该只是? extends Object.

Yet searching through the spec, there is no evidence at all that a wildcard must have an upper bound (or lower bound). The "unbounded" ?is treated consistently distinctly from bounded wildcards.

然而,通过规范搜索,根本没有证据表明通配符必须具有上限(或下限)。“无界”?与有界通配符的处理方式一致。

We could deduce from subtyping rules, that List<?>and List<? extends Object>are subtypes of each other, i.e., they are basicallythe same type. (The deduction depends on the fact that Ein interface List<E>has an implicit upper bound Object; but the rules do not require bounds on wildcards)

我们可以从子类型规则中推断出,List<?>List<? extends Object>是彼此的子类型,即它们基本上是相同的类型。(推论取决于Eininterface List<E>具有隐式上限的事实Object;但规则不需要通配符的界限)

Nevertheless the spec treats the two differently. For example http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7List<?>is a reifiable type, but List<? extends Object>is not, which means

尽管如此,规范对两者的处理方式不同。例如http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7List<?>是可具体化的类型,但List<? extends Object>不是,这意味着

    // ok
    List<?>[] xx = {};
    // fail
    List<? extends Object>[] yy = {};

    // ok
    boolean b1 = (y instanceof List<?>);
    // fail
    boolean b2 = (y instanceof List<? extends Object>);

I don't understand why though. It seems perfectly fine to say a wildcard must have an upper bound and a lower bound, default to Objectand null type.

我不明白为什么。可以说通配符必须有上限和下限,默认为Objectand null type

回答by barfuin

Both are the same because all objects in Java extend Object. I would prefer List<?>because it's more concise.

两者是相同的,因为 Java 中的所有对象都扩展Object. 我更喜欢,List<?>因为它更简洁。

回答by Alex DiCarlo

Similar to how MyClass extends Objectfor every class List<? extends Object>is the same as List<?>.

类似于 how MyClass extends Objectfor each classList<? extends Object>是一样的List<?>

回答by Bohemian

Although I'm plagiarising Marko, for which I apologise, his comment is the correct answer.

虽然我抄袭了 Marko,对此我深表歉意,但他的评论是正确的答案。

There is no difference, because implicitly every type extends Object.

没有区别,因为隐式每个类型extends Object