Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制。
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括了:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(using)、和卸载(Unloading)七个阶段。其中验证、准备和解析三个部分统称为连接(Linking),如下如所示。


这七个阶段,加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类的加载过程必须按照这个顺序来按部就班地开始,而解析阶段则不一定,它在某些情况下可以在初始化阶段后再开始。

类的生命周期的每一个阶段通常都是互相交叉混合式进行的,通常会在一个阶段执行的过程中调用或激活另外一个阶段。
Java虚拟机规范没有强制性约束在什么时候开始类加载过程,但是对于初始化阶段,虚拟机规范则严格规定了有且只有四种情况必需立即对类进行“初始化”(而加载、验证、准备阶段则必需在此之前开始),这四种情况归类如下:

1.遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令最常见的Java代码场景是:使用new关键字实例化对象时、读取或者设置一个类的静态字段(被final修饰、已在编译器把结果放入常量池的静态字段除外)时、以及调用一个类的静态方法的时候。
2.使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
3.当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要触发父类的初始化。
4.当虚拟机启动时,用户需要指定一个执行的主类(包含main()方法的类),虚拟机会先初始化这个类。
对于这四种触发类进行初始化的场景,在java虚拟机规范中限定了“有且只有”这四种场景会触发。这四种场景的行为称为对类的主动引用,除此以外的所有引用类的方式都不会触发类的初始化,称为被动引用。

下面通过三个实例来说明被动引用:

示例1:

  1. 父类SuperClass.java
  2. public class SuperClass {
  3. static{
  4. System.out.println("SuperClass init!");
  5. }
  6. public static int value = 123;
  7. }
  8. 子类SubClass.java
  9. public class SubClass extends SuperClass {
  10. static{
  11. System.out.println("SubClass init!");
  12. }
  13. }
  14. 主类NotInitialization.java
  15. public class NotInitialization {
  16. public static void main(String[] args) {
  17. System.out.println(SubClass.value);
  18. }
  19. }
  1. 输出结果:
  2. SuperClass init!
  3. 123

由结果可以看出只输出了“SuperClass init!”,没有输出“SubClass init!”。这是因为对于静态字段,只有直接定义该字段的类才会被初始化,因此当我们通过子类来引用父类中定义的静态字段时,只会触发父类的初始化,而不会触发子类的初始化。

示例2:

  1. SuperClass[ ]   scs=new SuperClass[11];

如上,当初始化一个对象数组的时候,也不会触发类的初始化。

示例3:

  1. public class ConstClass {
  2. static {
  3. system.out.printl("const");
  4. }
  5. public static final int age =123;
  6. }
  7. public class NotInitialization{
  8. public static void main(String[ ] args){
  9. system.out.println(ConstClass.age);
  10. }

此时并不会出现 “const”,因为在NotInitialization类在编译的时候已经把ConstClass中的变量age放在常量池中了,访问时直接取出age即可,不会引发ConstClass的初始化。

JVM中java类的加载时机(转载:http://blog.csdn.net/chenleixing/article/details/47099725)的更多相关文章

  1. 转:Java面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101

    Java面试题集(51-70) Java程序员面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101 摘要:这一部分主要 ...

  2. java之比较两个日期大小----https://blog.csdn.net/dongfangbaiyun/article/details/51225469

    https://blog.csdn.net/dongfangbaiyun/article/details/51225469 java之比较两个日期大小 最近又用到两个日期大小的比较,因此记录在此,方便 ...

  3. JVM:Java 类的加载机制

    虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验,转换,解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是虚拟机的类加载机制. 类的生命周期 类从被加载到虚拟机内 ...

  4. Java类的加载时机

    但是对于初始化阶段,虚拟机规范则是严格规定了有且只有5种情况必须立即对类进行“初始化”(而加载.验证.准备自然需要在此之前开始):1)遇到new.getstatic.putstatic或invokes ...

  5. TCP协议中的三次握手和四次挥手(图解)(转载http://blog.csdn.net/whuslei/article/details/6667471)

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源 ...

  6. Python 去除列表中重复的元素(转载http://blog.csdn.net/zhengnz/article/details/6265282)

    比较容易记忆的是用内置的set l1 = ['b','c','d','b','c','a','a']l2 = list(set(l1))print l2   还有一种据说速度更快的,没测试过两者的速度 ...

  7. UML类图几种关系的总结(转载 http://blog.csdn.net/tianhai110/article/details/6339565 )

    http://blog.csdn.net/tianhai110/article/details/6339565

  8. Java虚拟机(三):Java 类的加载机制

    1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...

  9. jvm系列(一):java类的加载机制

    java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...

随机推荐

  1. php 购物车完整实现代码

    1.商品展示页面 代码如下: <table width="255" border="0" cellspacing="0" cellpa ...

  2. C#接收post数据

    private string PostInput() { try { System.IO.Stream s=Request.InputStream; ; ]; StringBuilder builde ...

  3. PHP: 使用CURL访问FTP

    今天要做FTP上传.本想用PHP自带的FTP函数来实现,结果发现这个模块没有编译进来,重新编译PHP太麻烦,改用其他方式实现吧  FTP上传 if (isset($_POST['Submit'])) ...

  4. MapReduce程序开发之流量求和(八)

    1.分析记录手机流量的日志. 2.拿到日志中的一行数据,切分各个字段,抽取出我们需要的字段:手机号,上行流量,下行流量,然后封装成kv发送出去 3.使用java中的map方法: public clas ...

  5. [BZOJ 3236] [Ahoi2013] 作业 && [BZOJ 3809] 【莫队(+分块)】

    题目链接: BZOJ - 3236   BZOJ - 3809 算法一:莫队 首先,单纯的莫队算法是很好想的,就是用普通的第一关键字为 l 所在块,第二关键字为 r 的莫队. 这样每次端点移动添加或删 ...

  6. Struts 2 标签

    注:要使用Strust 2标签需<%@ taglib prefix="s" uri="/struts-tags" %> 表单标签: .form标签 ...

  7. [OpenGL]VS2010配置OpenGL开发环境

    opengl概述 OpenGL(Open Graphics Library)是一个跨编程语言.跨平台的专业图形程序接口. OpenGL是SGI公司开发的一套计算机图形处理系统,是图形硬件的软件接口,任 ...

  8. 【HDOJ】2896 病毒侵袭

    AC自动机模板题. #include <iostream> #include <cstdio> #include <cstring> #include <qu ...

  9. OpenCV 2.4.3在VS2010上的应用

    一.下载和安装:    1.OpenCV 2.4.3下载:http://www.opencv.org.cn/index.php/Download#Version_2.4.3    2.下载完成后,解压 ...

  10. bzoj1135

    POI阴影又发作了但这道题挺好的,比较涨知识裸的想法是裸的每次二分图匹配,但显然会TLE这里就要引入Hall定理:二分图G中的两部分顶点组成的集合分别为X, Y, X={X1, X2, X3,X4,. ...