您的位置:首页 > 编程语言 > Java开发

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>,擦除动作到这这两个方法的特征签名变得一模一样。这样就导致了编译错误。
      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: