Java 擦除-编译后的泛型类型信息
我在一本书中偶然发现了下面的内容-Java 擦除-编译后的泛型类型信息,java,generics,type-erasure,Java,Generics,Type Erasure,我在一本书中偶然发现了下面的内容- //Here, T is bound by Object by default. class Gen<T> { T ob; // here, T will be replaced by Object Gen(T o) { ob = o; } //Return ob. T getob() { return ob; } } 然而,我看到了这一点- public class G
//Here, T is bound by Object by default.
class Gen<T> {
T ob; // here, T will be replaced by Object
Gen(T o) {
ob = o;
}
//Return ob.
T getob() {
return ob;
}
}
然而,我看到了这一点-
public class GenStr<T extends java.lang.String> {
T str;
GenStr(T);
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: aload_1
6: putfield #2 // Field str:Ljava/lang/String;
9: return
T getstr();
Code:
0: aload_0
1: getfield #2 // Field str:Ljava/lang/String;
4: areturn
}
公共类GenStr{
T-str;
GenStr(T);
代码:
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:aload_0
5:aload_1
6:putfield#2//fieldstr:Ljava/lang/String;
9:返回
T getstr();
代码:
0:aload_0
1:getfield#2//fieldstr:Ljava/lang/String;
4:轮到你了
}
class-Gen{
T-ob;
Gen(T);
代码:
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:aload_0
5:aload_1
6:putfield#2//fieldob:Ljava/lang/Object;
9:返回
T getob();
代码:
0:aload_0
1:getfield#2//fieldob:Ljava/lang/Object;
4:轮到你了
}
为什么.class
文件仍然显示形式类型参数
为什么.class文件仍然显示形式类型参数
简单:所以
- 在编译时,编译器可以读取这样的.class文件并理解相应的类是泛型的,并且可以在源代码中作为泛型使用
- 在运行时,一些代码可以检查该类的泛型性质
Gen
是泛型的呢 关于类的类型信息仍然保留。不显示有关单个实例的类型信息
因此,您知道Gen
有一个类级别的类型参数(概念上)称为T
您不知道运行时Gen
实例的t
。您甚至无法从getob
中确定它:这仅仅给出了类型的下限(例如,如果getob
返回字符串
,t
可以是字符串
,字符序列
,可序列化
或对象
)。如果它返回null
,那么T
可以是任何东西
您可以针对没有源代码的类(只有编译的字节码)用Java编写代码。编译器需要有关此类类的泛型的信息,以便能够确保正确使用它们。为什么
文件不显示泛型参数?泛型仅在运行时被擦除。
class Gen extends java.lang.Object{
java.lang.Object ob;
Gen(java.lang.Object);
java.lang.Object getob();
}
class GenStr extends java.lang.Object{
java.lang.String str;
GenStr(java.lang.String);
java.lang.String getstr();
}
public class GenStr<T extends java.lang.String> {
T str;
GenStr(T);
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: aload_1
6: putfield #2 // Field str:Ljava/lang/String;
9: return
T getstr();
Code:
0: aload_0
1: getfield #2 // Field str:Ljava/lang/String;
4: areturn
}
class Gen<T> {
T ob;
Gen(T);
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: aload_1
6: putfield #2 // Field ob:Ljava/lang/Object;
9: return
T getob();
Code:
0: aload_0
1: getfield #2 // Field ob:Ljava/lang/Object;
4: areturn
}