泛型擦除的那些事

泛型简介

泛型咱们必定再了解不过了,java 中的集结类:ArrayList,HashMap

或许是,为了避免重复的模板代码,自jvm调优工具界说模板方法:

public  class Schedjson解析uleTemplate<T> {
public T doSchedule(T name){
//some code
return name;
}
}

在运用的时分,直接在尖括号内< >传入类型gitee参数,就能够避免许多烦人的强制类型转gitlab化。

ScheduleTemplate<String> scheduleTemplate = new ScheduleTemplate<>();
String name = scheduleTemplate.doSchedulgiti轮胎e("aaa");

本文的要点在于泛型擦除,泛型的运用不再过多介绍。

泛型擦除

证明存在泛型擦除

仍是运用上面的 ScheduleTemgit教程plate 类,这次咱们运用虚拟机linux javap 看一下。

 9: ldc           #4                  // String aaa
11: invokevirtual #5                  // Method git/frank/generics/ScheduleTemplajvm垃圾收回机制te.doSchedule:(Ljava/javaeelang/Object;)Ljava/lang/Object;
14: checkcast     #6                  // class javajvm内存结构/lang/Stringjvm参数
17: astore_2

json文件是干什么的的出来,在从源文件解释为class文件时,现已把泛型信息去掉了,取而代之的是强制类型转化 check虚拟机linuxcast

再或许,咱们能够经过运行时java怎样读来看:

SchegitlabduleTemplate<String> strTemplate = new ScheduleTemplate<&gt虚拟机;();
ScheduleTemplate<Integer> intTemplate = new ScheduleTemplate<&jsonp跨域原理gt;();
System.out.pri虚拟机安装教程ntln(strTemplate.getClass() == intTemplate.gjvm参数etCljava面试题ass());

java 为什么要泛型擦除

咱们先来看一下 java 中方针的布局:

泛型擦除的那些事

假定没有泛型擦除的话

假定不做泛型擦除的话,运用上面的比方,应该是下面这个姿态:

泛型擦除的那些事

回想一下,你有多虚拟机安装教程依靠 java 供应的集结类型。

要不是有泛型擦除机制,方法区中将会充斥着各种集结对应的类型数据,例如:ArrayListgiti轮胎<String>,ArrayList&json是什么意思lt;Integer>,ArrayList<XXX>,HashMap<String,XXX>,这样的话,办虚拟机对电脑伤害大吗法区会被许多的几乎无用的类型信息填满。

怎样”避免”json文件是干什么的泛型擦除

界说擦除上限

仍是开头的比方,这次我这样界说SchedugitlableTemplate

public  class ScheduleTemplate<T extejsonnds Number> {
p虚拟机是什么意思ublic T doSchedule(T name){
//some code
return njvm内存模型ame;
}
}

泛型界说中约束了有必要是Number类型,所以咱们的检验代码修改成这样:

ScheduleTemplate<Long> longTemplate = new ScheduleTemplate<&gJavat;();
Long  a = longTemplate.doSchedule(1L);

运用 javap 再看一下,这次泛型只擦除到了 Number ,而没有一路终究虚拟机安装教程win10 Object

10: invokestatijava言语c  #4                  // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
13: invokevirtual #5                  // Method git/frank/generics/ScheduleTemplate.doSchedule:(LjavaJSON/la虚拟机下载手机版ng/Number;)Ljava/lang/Number;
16: checkcast     #6                  // class java/langgit指令/Long

当然在运行时也是相同能够获取到 Number 类型的。

泛型擦除的那些事

运用承继避免“擦除”

上面咱们说过,泛型擦除的呈现是为了避免呈现过多的类信息而规划的。

假定咱们想避开泛型擦除的话,让虚拟机额外给我创立一个类信息就能够了。最简略的方法,便是运用承继。虚拟机对电脑伤害大吗

仍是运用上面的比方,这次我承继他创立了类 StrSchedulejava模拟器TemplateImpl

public class StrScheduleTemplateImpl extends ScheduleTemplate<Stringgithub&g虚拟机linuxt; {
@Override
public StriJSONng doSchedule(String name) {
return super.doSjson文件是干什么的chedule(name);
}java难学吗
}

现在,咱们再运用 javap 看一下。

 9: ldc           #4                  // String aaa
11: invokevirtual #5                  // Method git/franJSONk/generics/impl/StrScheduleTemplateImpl.doSchedule:(Ljavajsonp/lang/String;)Ljava/lang/String;
14: astore_2

相同github永久回家地址的,在运行时也能够获取到类型信息。

在实践运用中,大多运用匿名内部类的方法:

ScheduleTemplate scheduleTemplate = new ScheduleTempljvm原理ate<Strin虚拟机linuxg>(){};

泛型擦除的那些事

这种运用内部类的泛型传递方法在结构中使用非常广泛jvm参数,咱们最了解的应该便是 fastJson 中的 TypeReference吧~

总结

在 javajvm调优 中,在源代码编译为 class 文件后jvm调优面试题,泛型信息就JSON现已被抹除掉了。

尽管泛型擦除机制被许多人诟病,但泛型擦除能够大大削减在运行时 JVM 被逼保存过多的类型信息。

假定,你真的需求在运行时获取到泛型,能够经过匿名内部类的方法结构方针,使其能够将泛型保存至运行时。github