类型擦除是Java在处理泛型的一种方式,如Java的编译器在编译以下代码时:
public class Foo<T> {
T bar;
void doSth(T param) {
}
};
Foo<String> f1;
Foo<Integer> f2;
在编译后的字节码文件中,会把泛型的信息擦除掉:
public class Foo {
Object bar;
void doSth(Object param) {
}
};
也就是说,在代码中的Foo
所以说泛型技术实际上是Java语言的一颗语法糖,因为泛型经过编译器处理之后就被擦除了。
这种擦除的过程,被称之为——类型擦除。所以类型擦除指的是通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且在必要的时候添加类型检查和类型转换的方法。
类型擦除可以简单的理解为将泛型java代码转换为普通java代码,只不过编译器更直接点,将泛型java代码直接转换成普通java字节码。
泛型是一种编程范式,在不同的语言和编译器中的实现和支持方式都不一样。
通常情况下,一个编译器处理泛型有多种方式,在C++中,当编译器对以下代码编译时:
template<typename T>
struct Foo
{
T bar;
void doSth(T param) {
}
};
Foo<int> f1;
Foo<float> f2;
当编译器对其进行编译时,编译器发现要用到Foo
struct FooInt
{
int bar;
void doSth(int param) {
}
};
struct FooFloat
{
float bar;
void doSth(float param) {
}
};
这种做法,用起来的时候很方便,只需要根据具体类型找到具体的的类和方法就行了。但是问题是,当我们多次使用不同类型的模板时,就会创建出来的很多新的类,就会导致代码膨胀。