Pra*_*eek 27 java generics type-erasure
在计算中,具体化意味着一种类型的显式表示 - 即运行时类型信息.
oracle教程说,
可重新类型是类型信息在运行时完全可用的类型.这包括基元,非泛型类型,原始类型和未绑定通配符的调用.
不可再生类型是在编译时通过类型擦除删除信息的类型 - 未定义为无界通配符的泛型类型的调用.
如果类型是以下之一,则该类型是可恢复的:
- 一个原始类型(如
int)//理解- 阿非参数化类或接口类型(例如
Number,String或Runnable)//为什么- 一个参数化的类型,其中所有类型的参数是无界的通配符(例如
List<?>,ArrayList<?>或Map<?, ?>)//为什么- 原始类型(如
List,ArrayList或Map)//为什么- 阵列,其组件类型为reifiable(如
int[],Number[],List<?>[],List[],或int[][])//为什么
如果类型是以下之一,则该类型不可再生:
- 类型变量(例如
T)//为什么- 一个参数化的类型与实际的参数(如
List<Number>,ArrayList<String>或Map<String, Integer>)//为什么- 具有绑定(例如
List<? extends Number>或Comparable<? super String>)//为什么的参数化类型
为什么2,3,4,5是可以再生的,6,7,8是不可再生的?
LBC*_*LBC 11
Sun/Oracle说原因是需要的组合(编译时类型检查就足够了),代码大小(避免类似STL的代码膨胀)和性能(避免在运行时已经在编译时完成的类型检查):
类型擦除确保不为参数化类型创建新类; 因此,泛型不会产生运行时开销.
简而言之,1-5是可以恢复的,因为它们只是保持与代码中指定的相同类型,因此没有类型信息丢失/删除,但6-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>).
与前一个答案相同
你可以问谷歌同样的问题:
可再生型
当您使用泛型时,大多数情况下,编译时类型信息都会丢失.在运行时,通常所有程序都知道引用是对某种Object的引用.如果在运行时也知道所有类型信息,则该类型称为可恢复的.也许有一天将会重新设计仿制药,以便所有类型都可以恢复.