学习JVM的第二天

当执行以下代码的时候会发生什么呢

package com.example.demo.test;

import java.util.UUID;

public class MyTest2 {

    public static void main(String[] args){
        System.out.println(MyParent2.str);
    }
}

class MyParent2{
    public static final String str= UUID.randomUUID().toString();
    static {
        System.out.println("this is MyParent2");
    }
}

执行结束后,它的结果居然是

this is MyParent2
948f8c54-59ac-4151-88c0-df6d4cc2ee167

得出结论:当一个常量的值并非编译期间可以确定的,那么其值就不会被放到调用类的常量池中,这时在程序运行时会导致主动使用这个常量所在类,显然会导致这个类被初始化。

其实还有一个疑问,如果我创建的是这个类的数组,那么它的static代码块会不会被执行呢

package com.example.demo.test;


public class MyTest3 {

    public static  void main( String[] args){
        MyParent3[] myParent3s=new MyParent3[3];
        System.out.println(myParent3s.getClass());
    }

}


class MyParent3 {
    static {
        System.out.println("this is MyParent3");
    }
}

查看结果

class [Lcom.example.demo.test.MyParent3;

也就是说没有被初始化,这是为啥,我通过反编译之后查看结果发现助记符anewarray

anewarray:专门给对象创建数组而去使用的,给对象创建新数组还有newarray

通过执行查看结果,然后再去反编译

发现反编译之后的int类型数组是newarray助记符

当我new一个对象的时候,执行完成之后,再去反编译发现

new这个助记符就是在创建对象实例,也就是符合主动使用的要求,所以便会被初始化

总结:只有在对象主动使用的时候,该类文件才会被初始化,其他情况都是属于被动使用,并不会去初始化对象。那么对于对象数组一说,其实是在内存中开辟一块内存空间,用来存放该类型的固定长度的数组集。

补充:关于使用javap反编译的可以查看   https://www.jianshu.com/p/6a8997560b05

           更多参考java中的助记符,请看:package com.sun.org.apache.bcel.internal 包下的 Constants。

原创文章 46 获赞 24 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_39892293/article/details/105573774
今日推荐