JVM的类加载阶段中初始化阶段   P210

  虚拟机规定的五种情况必须对类的“初始化”情况

  1.遇到new、getstatic、putstatic、或invokestic 四条字节码指令时,如果类没有经过初始化,则需要先触发使其初始化,生成这四条指令的最常见的java代码场景时:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰,已在编译器把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。

  2.使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化则需要先触发其初始化。

  3.当初始化一个类的时候,入宫发现其父类还没有进行过初始化,则需要先触发其父类的初始化。

  4.当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。

  5.当使用JDK7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要先触发其初始化。

这五种情况属于------对一个类进行主动引用。

  除此之外,所有引用类的方式都不会触发初始化,成为被动引用

  一、通过子类引用父类的静态字段,不会导致字类初始化

public class SuperClass {
public static int value = 123;
static {
System.out.println("SuperClass init!!!");
}
}
public class SubClass extends SuperClass {
static {
System.out.println("SubClass init!!");
}
}
public class InitTest {
public static void main(String[] args) {
System.out.println(SubClass.value);
}
}
// 输出
// 子类调用父类的静态遍历,致使触发父类初始化,但是子类初始化未调用

可以打印出类的加载顺序,可以用来排查 class 的冲突问题:

-XX:+TraceClassLoading

  二、通过数组定义来引用类,不会触发此类的初始化

public static void main(String[] args) {
SuperClass[] sca = new SuperClass[10];
}
运行后没有触发"SuperClass init"但是newarray触发

 

三、常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量类的初始化

public class ConstClass {
static {
System.out.println("ConstClass init!!!"); public static final String HELLOWORLD = "hello world";
}
public static void main3(String[] args) {
System.out.println(ConstClass.HELLOWORLD);
}
没有触发"ConstClass init!!!"
  虽然在Java源码中引用了ConstClass类中的常量HELLOWORLD,但其实在编译阶段通过常量传播优化,已经将此常量ConstClass.HELLOWORLD的引用
实际都被转化成InitTest类对自身常量池的引用了。

  ps:

  调用 javap -c xx.class查看字节码 <https://www.jianshu.com/p/6a8997560b05>

  字节码大全 <https://www.cnblogs.com/longjee/p/8675771.html>

最新文章

  1. 移动端web开发——视口
  2. PHP 通过百度API 实现通过城市名称获取经度
  3. SQLSERVER2012 Audit (审核)功能
  4. 使用ueditor中的setContent() 时经常报innerHtml错误(笔记)
  5. css3立体旋转
  6. 输出有序数组的中两个元素差值为指定值diff的两个元素
  7. DEDE的data目录名称修改方法
  8. java5 新特性
  9. YARN应用程序开发流程(类似于MapReduce On Yarn)本内容版权归(小象学院所有)
  10. 开源TinyXML 最简单的新手教程
  11. Wise Registry Cleaner Pro(智能注册表清理) V9.31 绿色版
  12. 深入理解ES6之——迭代器与生成器
  13. 011_docker内部各系统基本工具安装
  14. [poj P2976] Dropping tests
  15. 为什么要用redis
  16. Memcaced多站点登录图解
  17. 20145306 网路攻防 web安全基础实践
  18. oracle 删除表的几种方法及回收站
  19. bzoj 5085: 最大——结论题qwq
  20. 写给测试人员:不是所有的bug都需要修复

热门文章

  1. Springboot项目中pom.xml的Oracle配置错误问题
  2. python机器学习---线性回归案例和KNN机器学习案例
  3. RabbitMQ高级面试题
  4. 解决Eclipe安装不上android的ADT的办法
  5. SQL Server强制释放内存
  6. javascript高级程序设计学习历程
  7. error: undefined reference to `vtable for
  8. 打包工具webpack和热加载深入学习
  9. 集合(set)
  10. 是否注意过isEmpty 和 isBlank 区别?