为什么以下类型在java中是可恢复和不可恢复的?

Pra*_*eek 27 java generics type-erasure

在计算中,具体化意味着一种类型的显式表示 - 即运行时类型信息.

oracle教程说,

可重新类型是类型信息在运行时完全可用的类型.这包括基元,非泛型类型,原始类型和未绑定通配符的调用.

不可再生类型是在编译时通过类型擦除删除信息的类型 - 未定义为无界通配符的泛型类型的调用.

如果类型是以下之一,则该类型是可恢复的:

  1. 一个原始类型(如int)//理解
  2. 阿非参数化类或接口类型(例如Number,StringRunnable)//为什么
  3. 一个参数化的类型,其中所有类型的参数是无界的通配符(例如List<?>,ArrayList<?>Map<?, ?>)//为什么
  4. 原始类型(如List,ArrayListMap)//为什么
  5. 阵列,其组件类型为reifiable(如int[],Number[],List<?>[],List[],或int[][])//为什么

如果类型是以下之一,则该类型不可再生:

  1. 类型变量(例如T)//为什么
  2. 一个参数化的类型与实际的参数(如List<Number>,ArrayList<String>Map<String, Integer>)//为什么
  3. 具有绑定(例如List<? extends Number>Comparable<? super String>)//为什么的参数化类型

为什么2,3,4,5是可以再生的,6,7,8是不可再生的?

LBC*_*LBC 11

Sun/Oracle说原因是需要的组合(编译时类型检查就足够了),代码大小(避免类似STL的代码膨胀)和性能(避免在运行时已经在编译时完成的类型检查):

类型擦除确保不为参数化类型创建新类; 因此,泛型不会产生运行时开销.

简而言之,1-5是可以恢复的,因为它们只是保持与代码中指定的相同类型,因此没有类型信息丢失/删除,但6-8将在编译期间丢失类型信息(<>之间的东西)所以可以不能在运行时访问.

  • @samshers STL 引用了 C++ 标准模板库,该库使用一种基于模板方法为每个特定类型生成代码的方法来实现“通用”类型,因此得名。 (3认同)
  • 我认为这个答案是最直接地回答问题的! (2认同)

Lea*_*ner 8

理解这两个术语的含义.

可恢复意味着其类型在运行时完全可用意味着java编译器不需要任何类型擦除过程.

Non-Reifiable意味着java编译器需要类型擦除过程,因为类型不完全可用.

如果类型是以下之一,则该类型是可恢复的:

1.基本类型(如int):

这里认为当你编写或使用任何int作为参考时,你认为编译器需要任何进程来识别int的类型吗?不,因为int是int ....对于所有原始类型都是相同的

2.非参数化类或接口类型(例如Number,String或Runnable)

我在前面的回答中告诉他的相同的答案,编译器不需要任何类型擦除Number,String或Runnable.

3.参数化类型,其中所有类型参数都是无界通配符(例如List <?>,ArrayList <?>或Map <?,?>)

所有无界通配符都被接受为可再生类型,因为它已在可再生类型的定义中提及,现在由API开发人员将其视为可再生类型.

4.原始类型(例如List,ArrayList或Map)::

与第一个问题相同的答案

5.一个组件类型可以重新生成的数组(例如int [],Number [],List <?> [],List []或int [] [])::

与第一个问题相同的答案

如果类型是以下之一,则该类型不可再生:

6.类型变量(如T):

因为java无法识别T的类型,所以编译器需要类型擦除来识别类型.

7.具有实际参数的参数化类型(例如List <Number>,ArrayList <String>或Map <String,Integer>):

这里所有类型都是泛型类型,在运行时编译器中将List列为List ...因此根据Non-refiable的定义,所有这些集合都被认为是不可恢复的.

8.带有绑定的参数化类型(例如List <?extends Number>或Comparable <?super String>).

与前一个答案相同

  • -1为什么你的意思是`编译器需要类型擦除来识别类型`?这非常令人困惑,而且很可能完全是错误的.据我所知,Java中类型擦除的主要原因是需要向后添加与添加泛型功能之前编写的代码. (2认同)

No *_*ame 7

你可以问谷歌同样的问题:

可再生型

当您使用泛型时,大多数情况下,编译时类型信息都会丢失.在运行时,通常所有程序都知道引用是对某种Object的引用.如果在运行时也知道所有类型信息,则该类型称为可恢复的.也许有一天将会重新设计仿制药,以便所有类型都可以恢复.


Saj*_*tta 7

可重新类型是类型信息在运行时完全可用的类型.这包括基元,非泛型类型,原始类型和未绑定通配符的调用.

不可再生类型是在编译时通过类型擦除删除信息的类型 - 未定义为无界通配符的泛型类型的调用.不可重新生成的类型在运行时没有提供所有信息.不可重定义类型的示例是List <String>和List <Number>; JVM无法在运行时区分这些类型.如"泛型限制"中所示,在某些情况下,不能使用不可重新生成的类型:例如,在表达式的实例中,或作为数组中的元素.

参考