从虚拟机层面看Java 中的数组

通过前面章节Java虚拟机类的加载时机的学习,我们知道new 一个类的时候如果这个类还没有初始化就会触发这个类的初始化。那么我们new 一个数组的时候会不会触发类的初始化呢?通过运行下面这个示例,我们可以看到MyTest类的静态代码块并没有执行,说明并没有触发MyTest类的初始化阶段。

package com.geekymv.test.jvm;

public class Test03Array {
    public static void main(String[] args) {
        MyTest[] myTests = new MyTest[1];
    }
}

class MyTest {
    static {
        System.out.println("MyTest static block");
    }
}

修改main方法,打印下myTests的class对象及父class对象。

public static void main(String[] args) {
    MyTest[] myTests = new MyTest[1];

    System.out.println(myTests.getClass());
    System.out.println(myTests.getClass().getSuperclass());
}

输出如下:

class [Lcom.geekymv.test.jvm.MyTest;
class java.lang.Object

说明MyTest[] myTests = new MyTest[1];这段代码里面触发了另外一个名为[Lcom.geekymv.test.jvm.MyTest的类的初始化。这并不是一个合法的类的名称,它是一个由Java虚拟机自动生成的,直接继承自java.lang.Object 类。

通过反编译工具javap反编译Test03Array类

javap -c com.geekymv.test.jvm.Test03Array

Compiled from "Test03Array.java"
public class com.geekymv.test.jvm.Test03Array {
  public com.geekymv.test.jvm.Test03Array();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1
       1: anewarray     #2                  // class com/geekymv/test/jvm/MyTest
       4: astore_1
       5: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
       8: aload_1
       9: invokevirtual #4                  // Method java/lang/Object.getClass:()Ljava/lang/Class;
      12: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      15: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
      18: aload_1
      19: invokevirtual #4                  // Method java/lang/Object.getClass:()Ljava/lang/Class;
      22: invokevirtual #6                  // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
      25: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      28: return
}

通过反编译后的字节码我们可以看出创建动作由字节码指令anewarray触发,助记符anewarray 表示创建一个引用类型(如类、接口、数组)数组,并将其引用值压入栈顶。

对于数组来说,Javadoc经常将构成数组的元素称为Component,实际上就是将数组降低一个维度后的类型。

「更多精彩内容请关注公众号geekymv,喜欢请分享给更多的朋友哦」
geekymv

发布了219 篇原创文章 · 获赞 42 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/Geek_ymv/article/details/102732823