列表 vs List

可能重复:
和?

我发现ListList List以相同的方式执行。 至于我,它们之间没有区别。 如果我不对,你能解释一下我的区别吗?

 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 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(), new Integer(1)); func2(new ArrayList(), new Integer(1)); List list1 = new ArrayList(); List list2 = new ArrayList(); List list3 = new ArrayList(); List list4 = new ArrayList(); } } 

这很复杂…

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

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

有人会认为对于通配符也是如此,并且? 应该只是一个简写? extends Object ? extends Object

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

我们可以从子类型规则推导出ListList List是彼此的子类型,即它们基本上是相同的类型。 (推论取决于interface List中的interface List具有隐式上限Object的事实;但规则不要求通配符上的边界)

然而,规范对待这两者的方式不同。 例如http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7 List是一个可重新生成的类型,但List List不是,这意味着

  // ok List[] xx = {}; // fail List[] yy = {}; // ok boolean b1 = (y instanceof List); // fail boolean b2 = (y instanceof List); 

我不明白为什么。 说通配符必须有上限和下限,默认为Objectnull type似乎很好。

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

类似于MyClass extends Object如何为每个类List MyClass extends Object List ListList相同。

虽然我正在抄袭Marko,为此我道歉,他的评论是正确答案。

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