Java泛型类型擦除
2018-02-24 16:11
225 查看
泛型是JDK1.5的一项新增特性,它的本质是参数化类型的应用,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口和泛型方法。
泛型技术在C#和Java之中的使用方式看似相同,但实现上却有着根本性的分歧,C#里面泛型无论在程序源代码中,编译后的IL中或是运行期的CLR中,都是切实存在的,List<Integer>和List<String>就是两个不同的类型,它们在系统运行期生成,有自己的虚方法表和类型数据,这种实现称为类型膨胀,基于这种方法实现的泛型称为真实泛型。
Java语言中的泛型规则则不一样,它只在程序源码中存在,在编译后的字节码文件中,就已经替换为原来的原生类型了,并且在相应的地方插入了强制类型转换的代码,因此对于运行期的Java语言来说,ArrayList<Integer>和ArrayList<String>就是同一个类,Java语言中的泛型实现方法称为类型擦除,基于这种方法实现的泛型称为伪泛型。看如下的代码实例:public class GenericTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("Hello", "上海");
map.put("Hi", "北京");
System.out.println(map.get("Hello"));
System.out.println(map.get("Hi"));
}
} 把这段Java代码编译成Class文件,然后再用字节码反编译工具进行反编译后,将会发现泛型都已经不见了,程序又变回了Java泛型出现之前的写法,泛型类型都变回了原生类型。代码清单如下:public class GenericTest {
public GenericTest() {
}
public static void main(String[] args) {
HashMap map =
4000
new HashMap();
map.put("Hello", "上海");
map.put("Hi", "北京");
System.out.println((String)map.get("Hello"));
System.out.println((String)map.get("Hi"));
}
} Java通过擦除法来实现泛型丧失了一些泛型思想应有的优雅,例如下面的代码: public class GenericTest {
public void method1(List<String> list){
System.out.println("Hello World");
}
public void method1(List<Integer> list){
System.out.println("Hello World");
}
} 上面的代码是不能编译成功的,因为参数List<String> list和List<Integer> list编译之后都被擦除了,变成了一样的原生类型List<E>,擦除动作到这这两个方法的特征签名变得一模一样。这样就导致了编译错误。
泛型技术在C#和Java之中的使用方式看似相同,但实现上却有着根本性的分歧,C#里面泛型无论在程序源代码中,编译后的IL中或是运行期的CLR中,都是切实存在的,List<Integer>和List<String>就是两个不同的类型,它们在系统运行期生成,有自己的虚方法表和类型数据,这种实现称为类型膨胀,基于这种方法实现的泛型称为真实泛型。
Java语言中的泛型规则则不一样,它只在程序源码中存在,在编译后的字节码文件中,就已经替换为原来的原生类型了,并且在相应的地方插入了强制类型转换的代码,因此对于运行期的Java语言来说,ArrayList<Integer>和ArrayList<String>就是同一个类,Java语言中的泛型实现方法称为类型擦除,基于这种方法实现的泛型称为伪泛型。看如下的代码实例:public class GenericTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("Hello", "上海");
map.put("Hi", "北京");
System.out.println(map.get("Hello"));
System.out.println(map.get("Hi"));
}
} 把这段Java代码编译成Class文件,然后再用字节码反编译工具进行反编译后,将会发现泛型都已经不见了,程序又变回了Java泛型出现之前的写法,泛型类型都变回了原生类型。代码清单如下:public class GenericTest {
public GenericTest() {
}
public static void main(String[] args) {
HashMap map =
4000
new HashMap();
map.put("Hello", "上海");
map.put("Hi", "北京");
System.out.println((String)map.get("Hello"));
System.out.println((String)map.get("Hi"));
}
} Java通过擦除法来实现泛型丧失了一些泛型思想应有的优雅,例如下面的代码: public class GenericTest {
public void method1(List<String> list){
System.out.println("Hello World");
}
public void method1(List<Integer> list){
System.out.println("Hello World");
}
} 上面的代码是不能编译成功的,因为参数List<String> list和List<Integer> list编译之后都被擦除了,变成了一样的原生类型List<E>,擦除动作到这这两个方法的特征签名变得一模一样。这样就导致了编译错误。
相关文章推荐
- Java泛型 类型变量的限定
- Java泛型:类型擦除
- Java泛型类型擦除导致的类型转换问题
- java泛型总结(类型擦除、伪泛型、陷阱)
- java泛型通配符和类型参数的范围
- java泛型:通过自定义ParameterizedType实现参数化类型中类型参数的替换
- Java泛型-类型擦除
- 详解Java泛型(四)之通配符类型
- JAVA泛型中的有界类型(extends super)
- java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题
- java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题
- java泛型 generics --- 第二部分 泛型方法 限制类型参量 泛型方法,限制类型参量
- java泛型程序设计——通配符类型+通配符的超类型限定
- Java泛型-类型擦除
- Java泛型 类型变量的限定
- Java泛型-类型擦除
- java泛型与类型擦出
- 使用Java泛型返回动态类型
- Java泛型与类型擦除
- Java泛型-类型擦除