我在一本书里偶然发现了下面的内容-
//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; }
}编译完这两个类后,Gen中的T将被Object替换。GenStr中的T将被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>
发布于 2019-05-31 04:05:10
为什么.class文件仍然显示形式类型参数?
很简单:所以
的泛型性质。
类型擦除指的是不保留有关用于实例化的泛型类的特定类型的信息。但是这个类是泛型的信息需要在类文件中。否则,在编译器看不到Gen而只看到Gen.class的情况下,编译器如何知道Gen.java是泛型的呢?!
发布于 2019-05-31 04:06:00
有关类的类型信息仍然保留。有关单个实例的类型信息不是。
因此,您知道Gen有一个名为T的类级类型参数(名义上)。
您不知道Gen实例在运行时的T。您甚至不能从getob中确定它:这只能给出类型的下限(例如,如果getob返回一个String,则T可以是String、CharSequence、Serializable或Object)。如果它返回null,那么T可以是任何东西。
您可以使用Java针对没有源代码的类编写代码,只有编译后的字节码。编译器需要有关这些类的泛型的信息,以便能够确保正确地使用它们的类型。
https://stackoverflow.com/questions/56384842
复制相似问题