了解泛型吗?
参考文章:https://blog.csdn.net/qq_43546676/article/details/128790980
泛型就是在编译时检查类型安全,并且不需要强制进行类型转换
泛型擦除了解吗?
泛型擦除即在编译生成的字节码中,所有声明泛型的地方都会被擦除,擦除之后设置的类型会根据是否指定泛型上界而不同:
-
如果没有指定泛型上界,则所有的泛型类型在编译之后都替换为 Object 类型
即在
generic.set("张三")
时,会将 String 类型的参数擦除为 Object 类型通过反编译指令
javap -c
得到字节码,发现在 11 行 set 值类型为 Object,在 15 行 get 值类型为 Object,在 18 行编译器会插入checkcast
语句将 Object 类型转为 String 类型public class GenericTest<T> {private T t;public T get(){return t;}public void set(T t) {this.t = t;}public static void main(String[] args) {GenericTest<String> generic = new GenericTest<>();generic.set("张三");generic.get();} } // 通过 javap -c 反编译得到字节码指令public static void main(java.lang.String[]);Code:0: new #3 // class com/example/nettystudy/AlgorithmTest/GenericTest3: dup4: invokespecial #4 // Method "<init>":()V7: astore_18: aload_19: ldc #5 // String 张三11: invokevirtual #6 // Method set:(Ljava/lang/Object;)V14: aload_115: invokevirtual #7 // Method get:()Ljava/lang/Object;18: checkcast #8 // class java/lang/String21: astore_222: return
-
如果指定泛型上界,则所有的泛型类型在编译之后都替换为 String 类型(也就是上界的类型)
可以发现在字节码第 11 行和第 15 行即 set 和 get 时,类型都为 String 类型,而不是 Object 类型
public class GenericTest<T extends String> {private T t;public T get(){return t;}public void set(T t) {this.t = t;}public static void main(String[] args) {GenericTest<String> generic = new GenericTest<>();generic.set("张三");String s = generic.get();} } // 通过 javap -c 反编译得到字节码 public static void main(java.lang.String[]);Code:0: new #3 // class com/example/nettystudy/AlgorithmTest/GenericTest3: dup4: invokespecial #4 // Method "<init>":()V7: astore_18: aload_19: ldc #5 // String 张三11: invokevirtual #6 // Method set:(Ljava/lang/String;)V14: aload_115: invokevirtual #7 // Method get:()Ljava/lang/String;18: astore_219: return