首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Java的泛型(Erasure)中检索类型信息?

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

Stack Overflow用户
提问于 2013-09-04 03:48:29
回答 4查看 123关注 0票数 1

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

代码语言:javascript
运行
复制
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

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

代码语言:javascript
运行
复制
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对象(上面生成的编译器)。但是这对于泛型是有效的,这可能会导致运行时错误。

代码语言:javascript
运行
复制
List<Object> test = new ArrayList<Object>();
            test.add("hello");
            test.add(new Integer(34));

最后,约书亚·布洛赫在第115页(第23项,有效java)中提到,Set<Object>是参数化类型,表示可以包含任何类型对象的集合;Set<?>是表示只能包含某些未知类型对象的集合的通配符类型,而Set是原始类型,选择退出泛型类型系统。

我明白他所说的话是甚麽意思。一些澄清会有帮助。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-09-04 03:50:15

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

关于通配符:

  • Set<Object>的泛型类型正是Object。您可以从它中插入和检索Object实例,但不能将Set<Integer>传递给需要Set<Object>的方法,因为该方法可能正在计划向集合中添加一个非Integer对象。
  • Set<?>具有未指定的泛型类型。一个方法可以以Object的形式从它中检索任何东西(因为所有东西都是Object),并且可以在它上调用通用方法,比如hashCodetoString,但是它不能向集合添加任何东西。
  • 正如您所提到的,Set是原始类型,不应该在新代码中使用。
票数 5
EN

Stack Overflow用户

发布于 2013-09-04 03:54:58

我不太确定,但我理解类型信息在运行时中丢失的是,在运行时没有办法证明集合是特定类型的。如果将String添加到集合中,则它将仅为String,但集合并不强制所有元素都应类型为String

票数 1
EN

Stack Overflow用户

发布于 2013-09-04 04:07:09

泛型由Java编译器实现,作为称为“擦除”的前端转换。类型擦除适用于泛型的使用。当使用泛型时,它们被转换为编译时检查和运行时类型转换为

由于类型删除机制,此代码:

代码语言:javascript
运行
复制
List<String> a = new ArrayList<String>();
a.add("foo");
String x = a.get(0);

获取将其编译为:

代码语言:javascript
运行
复制
List a = new ArrayList();
a.add("foo");
String x = (String) a.get(0);

注意,在类型擦除之后,将额外的强制转换插入编译后的代码。

PS:@chrylis已经对你的问题第二部分给出了很好的解释。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18605074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档