gpt4 book ai didi

java - 如何在 Java 的泛型(Erasure)中检索类型信息?

转载 作者:行者123 更新时间:2023-11-29 07:06:59 24 4
gpt4 key购买 nike

通过使用泛型,我们可以在编译期间检测到任何可能的情况。例如,

List<String> list = new ArrayList<String>();
//list.add(new Integer(45)); This will cause compilation error.
list.add("car");
list.add("bus");
list.add("bike");
String vehicle = list.get(0); //compiler-generated cast

当我们在 Java 1.5 之前使用原始类型而不是泛型时,它需要显式转换。例如,

List list2 = new ArrayList();
list.add("car");
list.add("bus");
list.add("bike");
String vehicle = (String)list.get(0); //explicit casting is necessary

但是对于泛型,会发生类型删除。那就是类型信息在运行时丢失了。如果是这样,那么 JVM 如何知道它在运行时检索的对象类型是字符串对象还是 person 对象(上面编译器生成的转换)。但这对泛型有效,这可能会导致运行时错误。

List<Object> test = new ArrayList<Object>();
test.add("hello");
test.add(new Integer(34));

最后,Joshua Bloch 在第 115 页(第 23 项,effective java)中提到 Set<Object>是参数化类型,表示可以包含任何类型对象的集合, Set<?>是一个通配符类型,表示一个只能包含某种未知类型的对象的集合和 Set是一种原始类型,它选择退出通用类型系统。

我确实明白他上面这句话的意思。一些澄清会有所帮助

最佳答案

编译器在从泛型方法中检索项目时插入强制转换操作;这是 JVM 知道处理 list.get(0) 结果的唯一方法作为 String .这就是为什么堆污染(将错误类型的对象插入泛型集合)会导致 ClassCastException 的原因。在运行时。

关于通配符:

  • Set<Object>的通用类型恰好是 Object .您可以插入和检索 Object它的实例,但你不能传递 Set<Integer>一个期待 Set<Object> 的方法,因为该方法可能计划添加一个非 Integer反对集合。
  • Set<?>具有未指定的通用类型。一个方法可以从中检索任何东西作为 Object (因为一切都是 Object )并且可以像 hashCode 一样调用通用方法或 toString , 但它不能向集合中添加任何内容。
  • Set ,正如您提到的,是原始类型,不应在新代码中使用。

关于java - 如何在 Java 的泛型(Erasure)中检索类型信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18605074/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com