zoukankan      html  css  js  c++  java
  • JVM -- 类的初始化

    《深入理解Java虚拟机》 第二版中介绍到了类的加载过程。

    一个类从加载入内存到卸载出内存为止,整个生命周期包括:

    Loading(加载)-----Verification(验证)-----Preparation(准备)-----Resolution(解析)-----Initialization(初始化)-----Using(使用)----Unloading(卸载)

    在Initalization 阶段,虚拟机规范严格定一个5种必须立即对类初始化的情况。

    1、遇到new ,getstatic putstatic invokestatic

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

    3、初始化一个类的时候,如果发现其父类还未初始化,那么首先初始化其父类。

    4、当虚拟机启动的时候,用户需要指定一个需要执行的主类,然后虚拟机才会初始化这个主类。

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

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

    1、通过子类调用父类中定义的静态字段,不会导致子类的初始化

     1 package volshell;
     2 
     3 public class SuperCalss {
     4     static {
     5         System.out.println("super class init");
     6     }
     7     public static int value = 23;
     8 }
     9 
    10 package volshell;
    11 
    12 public class SubClass extends SuperCalss {
    13     static {
    14         System.out.println("subclass init");
    15     }
    16 }
    17 
    18 package volshell;
    19 
    20 public class Demo1 {
    21     public static void main(String[] args) {
    22         System.out.println(SubClass.value);
    23     }
    24 }

    输出:

      super class init
      23
    对于静态字段,只有直接定义该字段的类才会被初始化,因此通过子类的来引用父类定义的静态字段,并不会触发子类的初始化。

    2、使用数组来定义引用类,不会触发该类的初始化。

      还是使用上面的代码在main方法中添加

      SuperCalss[]subClass = new SuperCalss[10];

    执行之后不会有任何的输出。

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

      同样还是使用上面的例子 ,将superClass 中的 value 设置为public static final int value=23; 设置为常量

    在主类中调用SuperClass.value

     执行结果;

      23

    在编译阶段,通过常量的传播优化,已将常量value存入Demo1 的常量池中了。

  • 相关阅读:
    session中删除数组中的某一个值
    Windows 查看端口占用进程并关闭
    Debian 9 / Debian 10 / Ubuntu 18.04 / Ubuntu 18.10快速开启BBR加速 或 关闭BBR加速
    在ASP.NET Web API 2中使用Owin OAuth 刷新令牌(示例代码)
    在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证
    Web API 2 的操作结果
    WebApi接口安全性 接口权限调用、参数防篡改防止恶意调用
    关于EF中使用Migrations的一些小提示
    Entity Framework 6 多对多增改操作指南
    用MVC5+EF6+WebApi 做一个考试功能(六) 仓储模式 打造EF通用仓储类
  • 原文地址:https://www.cnblogs.com/plxx/p/4528253.html
Copyright © 2011-2022 走看看