繁体   English   中英

泛型Java通配符和子类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM