我正在尝试了解以下代码段,在stackoverflow上搜索了关于lowerbound和upperbound的链接
试图克服以下几行的困惑,
si = s //好吗?对象数组可以隐式地转换为数组 整数?
etcdctl
感谢任何帮助
答案 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> ());
调用此功能现在,Double
和Integer
都会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
。