San*_*mar 23 java generics unbounded-wildcard
我正在阅读关于泛型的内容,我不明白是否需要未绑定的通配符以及它与原始类型的区别.我读了这个问题,但仍然没有弄清楚.在未绑定的通配符的 Java教程页面中,我得到了以下两点,我没有理解第一点:
- 如果您正在编写可以使用
Object类中提供的功能实现的方法.- 当代码使用泛型类中不依赖于类型参数的方法时.例如,
List.size()或List.clear().事实上,Class<?>经常使用,因为大多数方法Class<T>都不依赖T.
有人可以用外行语言解释未绑定的通配符和原始类型之间的区别.
有List<?>什么不同List<Object>?
ass*_*ias 36
如何
List<?>不同于List<Object>
主要区别在于第一行编译但第二行不编译:
List<?> list = new ArrayList<String> ();
List<Object> list = new ArrayList<String> ();
Run Code Online (Sandbox Code Playgroud)
但是,因为您不知道泛型类型List<?>是什么,所以不能使用其参数化方法:
List<?> list = new ArrayList<String> ();
list.add("aString"); //does not compile - we don't know it is a List<String>
list.clear(); //this is fine, does not depend on the generic parameter type
Run Code Online (Sandbox Code Playgroud)
至于与原始类型(没有泛型)的区别,下面的代码编译并运行正常:
List list = new ArrayList<String> ();
list.add("aString");
list.add(10);
Run Code Online (Sandbox Code Playgroud)
\n\n\n有人可以用外行语言解释一下未绑定通配符和原始类型之间的区别吗?
\n
未绑定的通配符类型可以保持collection\xe2\x80\x99s 类型 invariant,而原始类型则不能。正如 Joshua Bloch 在他的《Effective Java》中所说,
\n\n\n\n\n您可以将任何元素放入具有原始类型的集合中,很容易破坏集合\xe2\x80\x99s 类型不变性(如第 112 页上的 unsafeAdd 方法所示);您可以\xe2\x80\x99t 将任何元素(除 null 之外)放入 Collection<?> 中。
\n
因此,只要将参数化类型列表分配给未绑定通配符类型列表,就会保持Collection\xe2\x80\x99s 类型不变量。
\n\nList<String> list1 = new ArrayList();\nlist1.add("foo");\nlist1.add("bar");\nList<?> list2 = list1;\nRun Code Online (Sandbox Code Playgroud)\n\n如果您分配一个元素类型不同的原始类型列表,则未绑定通配符类型将不会维护collection\xe2\x80\x99s 类型 invariant,因为该列表最初是变体类型。
\n\nList list1 = new ArrayList();\nlist1.add(1);\nlist1.add("foo");\nList<?> list2 = list1;\nRun Code Online (Sandbox Code Playgroud)\n
如何List<?>不同于List<Object>?
List<Object> l1 = new ArrayList();
List<?> l2 = new ArrayList();
l1.add("Object");
//l2.add("Object"); incorrect
l2.add(null);
Run Code Online (Sandbox Code Playgroud)
您只能将空值添加到 List<?>
就我个人而言,我发现Java 教程中有关通配符的附加链接很有帮助。
List<?>我看到和之间的主要区别之一List是,前者只能用于读取它的元素(除非您真的想添加null),后者允许(未经检查)向其添加任意类型的对象,可能会出现意想不到的情况 -影响。
| 归档时间: |
|
| 查看次数: |
5820 次 |
| 最近记录: |