java—未绑定通配符和原始类型之间的区别

lhcgjxsq  于 2021-06-30  发布在  Java
关注(0)|答案(5)|浏览(234)

我读了一些关于泛型的文章,但我不理解对未绑定通配符的需求以及它与原始类型的区别。我读了这个问题,但还是不明白。在unbound通配符的java教程页面中,我得到了以下两点,但我不理解第一点:
如果您正在编写一个可以使用中提供的功能实现的方法 Object 班级。
当代码在泛型类中使用不依赖于类型参数的方法时。例如, List.size() 或者 List.clear() . 事实上, Class<?> 因为 Class<T> 不要依赖于 T .
有人能解释一下通配符和外行语言中原始类型的区别吗。
你怎么知道的 List<?> 不同于 List<Object> ?

oknwwptz

oknwwptz1#

有人能解释一下通配符和外行语言中原始类型的区别吗。
未绑定的通配符类型可以保持集合的类型不变,而原始类型不能。正如约书亚·布洛赫在他的《有效java》中所说,
您可以将任何元素放入具有原始类型的集合中,这很容易破坏集合的类型不变量(如第112页的unsafeadd方法所示);不能将任何元素(null除外)放入集合<?>。
因此,只要将参数化类型的列表分配给未绑定通配符类型的列表,集合的类型不变量就将保持不变。

List<String> list1 = new ArrayList();
list1.add("foo");
list1.add("bar");
List<?> list2 = list1;

如果为其元素属于不同类型的原始类型分配列表,则未绑定通配符类型将不会保持集合的类型不变,因为该列表最初是variant类型。

List list1 = new ArrayList();
list1.add(1);
list1.add("foo");
List<?> list2 = list1;
64jmpszr

64jmpszr2#

怎样 List<?> 不同于 List<Object> 主要区别在于第一行编译,而第二行不编译:

List<?> list = new ArrayList<String> ();
List<Object> list = new ArrayList<String> ();

但是,因为您不知道 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

至于与原始类型(没有泛型)的区别,下面的代码编译和运行良好:

List list = new ArrayList<String> ();
list.add("aString");
list.add(10);
jc3wubiy

jc3wubiy3#

list在方法签名中非常有用,可以调用不需要类型参数的方法,例如,从列表读取或旋转列表。

void someMethod(List<?> list) {
  list.clear();  // I will never add anything to the list in here
}

您将永远不会添加任何内容或以其他方式修改列表中所包含的类型,因为在具有此签名的方法中,除了null之外,您无法向列表中添加任何内容,因此您永远不会破坏类型安全性。另一方面,您可以对原始列表执行任何操作,我们都知道这可能导致违反类型安全性。

void someMethod2(List list) {
 list.add(new WeaselFurBrush());  
}
List list1 = new ArrayList<String>();
someMethod2(list1);// oops
vxf3dgd4

vxf3dgd44#

怎样 List<?> 不同于 List<Object> ?

List<Object> l1 = new ArrayList();
    List<?> l2 = new ArrayList();
    l1.add("Object");
    //l2.add("Object");   incorrect
    l2.add(null);

只能将空值添加到 List<?>

xlpyo6sf

xlpyo6sf5#

就我个人而言,我发现java教程中关于通配符的附加链接非常有用。
我看到的主要区别之一 List<?> 以及 List 前者只能用于读取其元素(除非您真的想添加 null ),后者允许(未选中)向其中添加任意类型的对象,并可能产生意外的副作用。

相关问题