《深入理解Java虚拟机》Java语法糖 -自动装拆箱与泛型

《深入理解Java虚拟机》Java语法糖

1.自动拆装箱

如下的代码

 public static void main(String[] args) {

        ArrayList<Integer> its = new ArrayList<>();

        its.add(0);

        int result = its.get(0);

        System.out.println("result = " + result);
    }

对应的字节码

 0 new #2 <java/util/ArrayList>
 3 dup
 4 invokespecial #3 <java/util/ArrayList.<init> : ()V>
 7 astore_1
 8 aload_1
 9 iconst_0
10 invokestatic #4 <java/lang/Integer.valueOf : (I)Ljava/lang/Integer;>
13 invokevirtual #5 <java/util/ArrayList.add : (Ljava/lang/Object;)Z>
16 pop
17 aload_1
18 iconst_0
19 invokevirtual #6 <java/util/ArrayList.get : (I)Ljava/lang/Object;>
22 checkcast #7 <java/lang/Integer>
25 invokevirtual #8 <java/lang/Integer.intValue : ()I>
28 istore_2
29 getstatic #9 <java/lang/System.out : Ljava/io/PrintStream;>
32 new #10 <java/lang/StringBuilder>
35 dup
36 invokespecial #11 <java/lang/StringBuilder.<init> : ()V>
39 ldc #12 <result = >
41 invokevirtual #13 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;>
44 iload_2
45 invokevirtual #14 <java/lang/StringBuilder.append : (I)Ljava/lang/StringBuilder;>
48 invokevirtual #15 <java/lang/StringBuilder.toString : ()Ljava/lang/String;>
51 invokevirtual #16 <java/io/PrintStream.println : (Ljava/lang/String;)V>
54 return

可以看偏移量10 和 偏移量25的指令 ,通过调用对应包装类的ValueOf方法完成装箱,调用intValue方法完成拆箱

invokestatic #4 <java/lang/Integer.valueOf : (I)Ljava/lang/Integer;>

25 invokevirtual #8 <java/lang/Integer.intValue : ()I>

2. 泛型与类型擦除

 0 new #2 <java/util/ArrayList>
 3 dup
 4 invokespecial #3 <java/util/ArrayList.<init> : ()V>
 7 astore_1
 8 aload_1
 9 iconst_0
10 invokestatic #4 <java/lang/Integer.valueOf : (I)Ljava/lang/Integer;>
13 invokevirtual #5 <java/util/ArrayList.add : (Ljava/lang/Object;)Z>
16 pop
17 aload_1
18 iconst_0
19 invokevirtual #6 <java/util/ArrayList.get : (I)Ljava/lang/Object;>
22 checkcast #7 <java/lang/Integer>
25 invokevirtual #8 <java/lang/Integer.intValue : ()I>
28 istore_2
29 getstatic #9 <java/lang/System.out : Ljava/io/PrintStream;>
32 new #10 <java/lang/StringBuilder>
35 dup
36 invokespecial #11 <java/lang/StringBuilder.<init> : ()V>
39 ldc #12 <result = >
41 invokevirtual #13 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;>
44 iload_2
45 invokevirtual #14 <java/lang/StringBuilder.append : (I)Ljava/lang/StringBuilder;>
48 invokevirtual #15 <java/lang/StringBuilder.toString : ()Ljava/lang/String;>
51 invokevirtual #16 <java/io/PrintStream.println : (Ljava/lang/String;)V>
54 return

我们创建的集合指定的泛型为Integer,而查看字节码信息,发现却变成了Object

13 invokevirtual #5 <java/util/ArrayList.add : (Ljava/lang/Object;)Z>
19 invokevirtual #6 <java/util/ArrayList.get : (I)Ljava/lang/Object;>

这是因为对JVM来说,不存在泛型。Java编译器会将泛型转化为当前泛型所能指代的类中的最高父类。

如果有声明继承的类的泛型,将转换为声明父类的类型

  public static void main(String[] args) {

        ArrayList<Dog> its = new ArrayList<>();

        Dog e = new Example().new Dog();
        its.add(e);

    }


    class Dog {

    }
 0 new #2 <java/util/ArrayList>
 3 dup
 4 invokespecial #3 <java/util/ArrayList.<init> : ()V>
 7 astore_1
 8 new #4 <Example$Dog>
11 dup  public static void main(String[] args) {

        ArrayList<Dog> its = new ArrayList<>();

        Dog e = new Example().new Dog();
        its.add(e);

    }


    class Dog extends Animal{

    }
12 new #5 <Example>
15 dup
16 invokespecial #6 <Example.<init> : ()V>
19 dup
20 invokevirtual #7 <java/lang/Object.getClass : ()Ljava/lang/Class;>
23 pop
24 invokespecial #8 <Example$Dog.<init> : (LExample;)V>
27 astore_2
28 aload_1
29 aload_2
30 invokevirtual #9 <java/util/ArrayList.add : (Ljava/lang/Object;)Z>
33 pop
34 return

  public static void main(String[] args) {

        ArrayList<Dog> its = new ArrayList<>();

        Dog e = new Example().new Dog();
        its.add(e);

    }


    class Dog extends Animal{

    }
    
    class Animal{

    }
 0 aload_0
 1 aload_1
 2 putfield #1 <Example$Dog.this$0 : LExample;>
 5 aload_0
 6 aload_1
 7 invokespecial #2 <Example$Animal.<init> : (LExample;)V>
10 return

猜你喜欢

转载自blog.csdn.net/JAVAlife2021/article/details/130714650
今日推荐