我是JAVA中一些内置数据结构的新手,在使用LinkedList时观察到这段代码不会引发错误:
LinkedList<?> list = new LinkedList<Integer>();
谁能给我解释一下我们怎么能把这作为一个有效的声明?我正在使用Eclipse,它在初始化时没有显示任何错误。然而,在此之后添加元素在这种情况下不起作用。
In
LinkedList<?> list;
您正在声明类型为LinkedList
的名为list
的变量,并提供通配符?
作为绑定到LinkedList
的类型参数T
的类型参数。所以list
的类型是LinkedList<?>
。这个通配符?
将捕获某种类型,但是该类型将是未知的并且不可用。
new LinkedList<Integer>();
是一个实例创建表达式。您正在创建类型为LinkedList
的实例,同时提供类型为Integer
的类型参数以绑定到LinkedList
的类型参数T
。因此,实例创建表达式的类型将是LinkedList<Integer>
。
注意,您将通过类型为LinkedList<?>
的变量list
与创建的LinkedList
进行交互。因此,不管您使用什么类型参数来创建它,现在都是通过LinkedList<?>
类型的值来查看它。
现在,您可以将类型为LinkedList<Integer>
的值赋给类型为LinkedList<?>
的变量,因为LinkedList<?>
是LinkedList<Integer>
的超类型。我们可以详细说明为什么会出现这种情况,但规则在这里描述。
至于
LinkedList<?> list = new LinkedList<>();
符号<>
表示实例创建表达式的类型参数应该被推断出来。类型推断的规则是大量和复杂的。基本上,由于?
表示未知类型,我们唯一可以确定的是类型参数至少应该是Object
,因为它是所有类型的超类型。这就变成了推断的类型
?
作为泛型参数,基本意思是"任意类",Integer
绝对符合"任意类",因此不存在错误。在初始化期间不会出现错误,因为泛型在运行时不存在,所以一旦代码编译,您拥有的泛型类型并不重要(几乎无关紧要)