常见笔试题-泛型擦除

了解泛型吗?

参考文章: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/GenericTest
           3: dup
           4: invokespecial #4                  // Method "":()V
           7: astore_1
           8: aload_1
           9: ldc           #5                  // String 张三
          11: invokevirtual #6                  // Method set:(Ljava/lang/Object;)V
          14: aload_1
          15: invokevirtual #7                  // Method get:()Ljava/lang/Object;
          18: checkcast     #8                  // class java/lang/String
          21: astore_2
          22: 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/GenericTest
         3: dup
         4: invokespecial #4                  // Method "":()V
         7: astore_1
         8: aload_1
         9: ldc           #5                  // String 张三
        11: invokevirtual #6                  // Method set:(Ljava/lang/String;)V
        14: aload_1
        15: invokevirtual #7                  // Method get:()Ljava/lang/String;
        18: astore_2
        19: return
    

你可能感兴趣的:(面试题,java,开发语言)