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. 强制不使用“兼容性视图”的HTML代码(转)

    在IE8浏览器以后版本,都有一个“兼容性视图”,让不少新技术无法使用.那么如何禁止浏览器自动选择“兼容性视图”,强制IE以最高级别的可用模式显示内容呢?下面就介绍一段HTML代码. X-UA-Comp ...

  2. Play on Words

    poj1386:http://poj.org/problem?id=1386 题意:给你n个单词,问你是否能够通过调整单词的顺序存在这样的一个序列,使得 每个单词的首字母是前一个单词的尾字母. 题解: ...

  3. TinyMCE下载及使用

    1.TinyMCE下载 官方下载网址:http://www.tinymce.com/ 简体中文语言包下载:http://www.tinymce.com/i18n/index.php?ctrl=lang ...

  4. 第二章 Stream API

    引例: 1 List<String> strList = Arrays.asList("zhaojigang","nana","tiany ...

  5. Effective c++ 第一章 让自己习惯C++

    条款 01:c++是一个语言联邦而不是一种单一的语言, 它包括: 1.C语言:没有模版.没有异常.没有重载…… 2.Object-Oriented C++:class.析构函数.构造函数.封装.继承. ...

  6. The fundamental knowledge of Node JS.

    D3 JSJava scirpt is an awesome language for Internface Design.All Obejcts in JavaScirpt could be use ...

  7. HDNOIP201206施工方案

    HDNOIP201206施工方案 难度级别:A: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 c国边防军在边境某处的阵地是由n个地堡组成的. ...

  8. POJ 2112 Optimal Milking(Floyd+多重匹配+二分枚举)

    题意:有K台挤奶机,C头奶牛,每个挤奶机每天只能为M头奶牛服务,下面给的K+C的矩阵,是形容相互之间的距离,求出来走最远的那头奶牛要走多远   输入数据: 第一行三个数 K, C, M  接下来是   ...

  9. Dinic 模板

    #include <iostream> #include <cstring> #include <cstdio> #include <queue> us ...

  10. 从SG函数浅谈解决博弈问题的通法

    基于笔者之前对于几种二元零和博弈游戏的介绍,这里将其思想进行简单的提炼,并引出解决这类二元零和博弈游戏的强大工具——SG函数. 其实对于博弈游戏如Bash.Nim等基本类型,异或一些比较高级的棋类游戏 ...