下限通配符

时间:2015-06-27 04:57:36

标签: java generics bounded-wildcard

我正在尝试了解以下代码段,在stackoverflow上搜索了关于lowerboundupperbound的链接

试图克服以下几行的困惑,

  

si = s //好吗?对象数组可以隐式地转换为数组   整数?

etcdctl

感谢任何帮助

2 个答案:

答案 0 :(得分:2)

请记住,gnerics是为了编译器而不是运行时信息。

执行si = s时,您将一个名为Number的超类的List分配给一个变量,该变量可以引用一个Integer超类的List。

如果它是一个Number列表,它仍然是一个Integer超类的Something列表。

我们知道它实际上是对象的Arraylist,因为您之前已经分配过。

我们也知道Object的ArrayList扩展了Object of List。

对象列表是一个超类数字的列表,这就是之前作业的原因。

我们也知道List of Object是一个Integer超类的列表,但它与编译器无关,它只关心Number的任何超类也是Integer的超类。

答案 1 :(得分:1)

我想知道你是否清楚为什么要使用<? super Number>代替<? extends Number> ......

声明具有<? extends Number>类型的类型保证采用该类型的任何内容至少遵守Number的合同。但是给出这种类型列表的一段代码不能将新成员添加到列表中。请考虑以下代码:

void appendInteger (List <? extends Number> list) {
   list.add (new Integer (3)); // Compiler error on this line
}

您可以使用appendInteger (new ArrayList <Double> ());调用此功能现在,DoubleInteger都会Number扩展,因此编译后将接受该参数。但是你可以看到,如果允许附加,那么违反调用代码中声明的合同。因此,编译器不允许在使用<? extends T>声明的任何结构中添加或替换成员的任何代码。上述方法将导致编译器错误。

简而言之,对于上限范围的通配符类型,您可以读取项目,但不能将成员放入结构中。

相反,使用List <? super Number>表示列表中的对象不比Number更具体。考虑这种方法:

void getInteger (java.util.List <? extends Number> list) {
    Number n = list.get (0); // Compiler error on this line
}

代码不知道list中元素的类型是什么。所以编译器也会用这个方法呕吐。您可以在list中添加或替换Number继承路径中任何类型的对象。但要阅读列表成员,您必须将它们视为类型Object或使用类型转换:

Object v = list.get (0);  // this will work
Number n = (Number) list.get (0);  // this will also work

鉴于此知识,请再次查看si = s中涉及的对象。请记住,您无法从这些结构中读取项目,只能添加或替换成员。您可以在s中放置的任何对象也可以在si中使用。因此,可以将s分配给si