从虚拟机层面看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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值