以前你把我烧死了,我必须说我多次搜索这个问题,我仍然无法理解List <Object>和List <?>之间的区别
我读过的所有书都说在Java中,每个类都隐含着Object的子类.
但是我在这里看到了以下代码:
public static void printList(List<Object> list) {
for (Object elem : list)
System.out.println(elem + " ");
System.out.println();
}
Run Code Online (Sandbox Code Playgroud)
这段代码是错误的(故意用于教育目的),根据作者的原因是:
[...]只打印一个Object实例列表; 它不能打印List <Integer>,List <String>,List <Double>等,因为它们不是List <Object>的子类型
解决方案是:
public static void printList(List<?> list) {
for (Object elem: list)
System.out.print(elem + " ");
System.out.println();
}
Run Code Online (Sandbox Code Playgroud)
如您所见,唯一的区别是第一行:
public static void printList(List<Object> list) {
public static void printList(List<?> list) {
Run Code Online (Sandbox Code Playgroud)
这就是我的问题的原因:List <Object>和List <?>之间有什么区别?
毕竟是对象超类的全部与否?
如果有人可以帮我一个简单的解释(我是Java的新手),我将不胜感激.
先感谢您.
Rob*_*tti 19
?是一个"通配符".您可以通过不同方式使用它:
无界通配符:
?
Run Code Online (Sandbox Code Playgroud)
带上限的通配符:
? extends Object (or another class)
Run Code Online (Sandbox Code Playgroud)
带下限的通配符
? super Object (or another class)
Run Code Online (Sandbox Code Playgroud)
List <?> list;
Run Code Online (Sandbox Code Playgroud)
您可以list使用任何类型参数分配给任何列表.
List<? extends Number> list;
Run Code Online (Sandbox Code Playgroud)
您可以使用类型参数Number(或Integer,Float,ecc)分配任何List列表
List<? super Integer> list;
Run Code Online (Sandbox Code Playgroud)
您可以分配列出任何具有类型参数Integer的List,或者类型为Integer类型的类型(Number,Comparable,Serializable,Object ...)
宣言
List<Object> list;
Run Code Online (Sandbox Code Playgroud)
类似于
List<? super Object> list;
Run Code Online (Sandbox Code Playgroud)
因为你可以只为"列表"分配一个对象列表; 那么你可以这样使用列表:
list = new ArrayList<Object>();
list.add(new String(""));
list.add(new Integer(3));
Run Code Online (Sandbox Code Playgroud)
这String是一个子类型Object并不意味着它List<String>是一个子类型List<Object>.如果是,则编译以下代码:
List<String> strings = new ArrayList<String>();
List<Object> objects = strings;
objects.add((Integer) 1);
strings.get(0).charAt(0); // but the Integer 1 does not have a charAt method ...
Run Code Online (Sandbox Code Playgroud)
因此,List<String>不是子类型List<Object>.
这两个List<String>和List<Object>的亚型List<?>.但由于List<?>是更通用的类型,您无法知道add方法采用的类型:
List<String> strings = new ArrayList<String>();
List<?> objects = strings;
objects.add((Integer) 1); // does not compile
Run Code Online (Sandbox Code Playgroud)
其中一个主要区别是如何修改列表.以下效果很好
List<Object> l1;
l1.add(new Object()); // OK
Run Code Online (Sandbox Code Playgroud)
而第二种情况产生编译错误.
List<?> l2;
l2.add(new Object()); // Compile error
Run Code Online (Sandbox Code Playgroud)
我认为原因已在网站上多次辩论过了.总之,<?>意味着一个(如在一个)特定还未知类型.由于该类型不是编译时知道的,因此不允许修改列表.