[英]Generics Java Wildcards and Subtyping
我正在阅读Java atm中的泛型,并且运行缓慢会需要一些帮助。 我从Oracle自己的数据库中读取:
https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html
在底部,我们可以看到List<Integer>
是List<? extends Number>
的子类型List<? extends Number>
List<? extends Number>
我也遇到了这个stackoverflow问题:
Java泛型类型:List <?之间的区别 扩展Number>和列表<T扩展Number>
在一个答案中说:这是真的:
((List<Integer>)list).add((int) s);
我已经验证了,没关系。 但是我不完全理解。
如果通配符是Short类,并且我添加了一个大于2 ^ 15-1(= 32767)的数字,该怎么办?
我什至尝试了类似的方法,而且效果很好:
import java.util.*;
class CastingWildcard{
public static void main(String[] args){
List<? extends Number> list = new ArrayList<Short>();
int s=32770;
((List<Integer>)list).add((int) s);
System.out.println(list.get(0));
}
}
总结一下:为什么我可以投射List<? extends Number>
当通配符可能是Short甚至是Byte时, List<? extends Number>
到List<Integer>
,这也扩展了Number?
您可以将对象强制转换为任何对象,但是在运行时可能会失败。 但是,由于在运行时不存在泛型信息,因此您的代码本质上成为((List)list).add(s);
。 此时, list
将接受任何对象,而不仅仅是Number
。 泛型可以在编译期间帮助您避免强制转换并保持类型安全,但是在运行时它们不再重要。
强制转换使编译器忽略以下事实:类型可能不可分配。
在运行时,类型参数并不重要,请参见type erasure 。
ArrayList
内部将内容存储在Object[]
数组中,这意味着,如果“滥用”转换,则可以将任何引用类型添加到列表对象。
但是,检索对象时可能会遇到异常,因为get
语句中隐藏了强制转换。
例:
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
List<String> list2 = (List) list;
list2.add("Hello World");
Integer i = list.get(0); // works
String s = list2.get(3); // works
s = list2.get(1); // ClassCastException
i = list.get(3); // ClassCastException
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.