后端开发 \ Java \ 类型擦除

类型擦除

总点击81
简介:什么是类型擦除? 类型擦除指的是一些信息仅存在于源码阶段,编译之后就不存在。类型擦除在Java中有泛型,自动拆装箱。

什么是类型擦除?


类型擦除指的是一些信息仅存在于源码阶段,编译之后就不存在。类型擦除在Java中有泛型,自动拆装箱。


泛型信息仅存在于代码编译阶段,进入JVM之前,与反向相关信息会被擦除。即泛型类和普通类在Java虚拟机内没有任何区别。

通过代码看编译之后类的类型类:

package CODE.泛型;

class Me<T>

{

private T data;

}

public class Erase

{

public static void main(String[] args)

{

Me<String> m1=new Me<>();

Me<Integer> m2=new Me<>();

//打印两个在jvm中的Class,获得类型的类型类

System.out.println(m1.getClass()); //class CODE.泛型.Me

System.out.println(m2.getClass()); //class CODE.泛型.Me

}

}

通过结果可以发现,泛型类在编译之后类型一样,也就是发生了类型擦除。

泛型类进入JVM之前,会进行类型擦除,之前泛型类的类型参数若没有指定上限,会被擦除为Object类。如果指定上限,则类型参数会被替换为相应类型上限。


代码如下:

import java.lang.reflect.Field;

class MyErase<T,E extends Number> // E 只能是Number及其子类

{

private T data1;

private E data2;

public MyErase(T data1,E data2)

{

this.data1=data1;

this.data2=data2;

}

}

//类型擦除

public class Erase

{

public static void main(String[] args)

{

MyErase<String,Integer> m1=new MyErase<>("pick",10);

Class cl=m1.getClass();

//getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。

Field[] field=cl.getDeclaredFields();

for(Field data :field)

{

//getType返回声明字段的类型

System.out.println(data.getType()); //class java.lang.Object class java.lang.Number

//由于会有类型擦除,T没有指定上限会被擦除为Object

//class java.lang.Object

//E extends Number,指定上限为Number,类型擦除后成为Number

//class java.lang.Number

}

}

}

意见反馈 常见问题 官方微信 返回顶部