java - 擦除 - 编译后的通用类型信息
问题描述
我在一本书中遇到了以下内容-
//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;
}
}
// Here, T is bound by String.
class GenStr<T extends String> {
T str; // here, T will be replaced by String
GenStr(T o) {
str = o;
}
T getstr() { return str; }
}
这两个类编译完成后,T
inGen
将被替换为Object
. T
in
将GenStr
替换为String
. javap
您可以通过在他们编译的类上运行来确认这一点。结果显示在这里:
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
}
为什么.class
文件仍然显示正式类型参数<T>
?
解决方案
为什么 .class 文件仍然显示正式类型参数?
简单:这样
- 在编译时,编译器可以读取这样的 .class 文件并理解相应的类是泛型的,并且可以在源代码中作为泛型使用
- 在运行时,以便某些代码可以检查,嗯,“反映”该类的通用性质
类型擦除是指有关用于实例化泛型类的特定类型的信息不被保留的事实。但是这个类是通用的信息需要在类文件中。Gen
在编译器看不到 Gen.java 而只看到 Gen.class 的情况下,编译器怎么会知道它是通用的?!
推荐阅读
- linux - 在 s390 上构建 MariaDB
- python-3.x - 酸洗 cv2.CascadeClassifier
- c++ - dlmopen 和 C++ 库
- javascript - 如何检查 html 是否有效?
- jquery - jquery ui可拖动防止点击外部
- javascript - 以最佳方式查找数组的某个子集
- android - 罕见异常“android.accounts.AuthenticatorException: ServiceDisabled”——这是什么意思?
- python - 如何查找哪个包需要我的其他包降级
- batch-file - 如何向 DOSKEY [CMD] 添加后缀
- python - 以块的形式从 dask 区域加载数据