标签:
---有助于理解JVM的运行过程
---更深入了解Java动态性(解热部署、动态加载),提高程序的灵活性
---最重要的一点儿是:有利于分析各种Web容器,Android插件化的原理
JVM将class文件加载到内存,并对数据进行校验、解析和初始化,最终形成JVM能够直接使用的Java类型的过程
抄图如下:
1、加载:
将字节码加载到内存中 ,并将这数据转换成方法区中运行的数据结构,在堆中生成一个表示这个类的java.lang.Class对象,作为方法区内数据的访问入口,当然这个过程需要类的加载器的参与
2、链接:
将Java类的二进制代码合并到JVM的运行状态中的过程,期间经过
1)验证:
--确保加载类的信息符合JVM规范,没有安全方面的问题
2)准备:
--正式为类变量(static变量)分配内存并设置类变量初始值的阶段,这些内存都在方法区中进行分配
注意:在准备阶段为类变量进行赋初值,比如static int a= 10;那么它的初始值是0,只有在初始化的时候,a的值才会变成10;
3)解析:
--虚拟机中常量池内的符号引用替换为直接引用的过程
注意字符串常量值:一般类名、方法名、参数名、变量名都属于常量。
3、初始化
1)初始化阶段是执行类构造器<clinit>()方法的过程,类构造器<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static块)中语句合并产生的。
类构造器是我们创建不了的。
2)当初始化一个类的时候,如果发现其父类还没有初始化,则需要先触发其父类的初始化
3)虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确的加锁和同步。
4)当访问一个Java类的静态域时,只有真正声明这个域的类才会被初始化。
此处需要一张图片
1.类的主动引用和被动引用(一定会发生类的初始化)
l new一个类的对象
l 调用类的静态成员(除了final常量)和静态方法
l 使用java.lang.reflect包的方法对类进行反射和调用
l 当虚拟机启动,java Demo则一定会初始化Demo类,就是先启动main方法所在的类
l 当初始化一个类,如果它的父类没有被初始化,则先会初始化它的父类
2.类的被动引用不会发生初始化
l 通过数组定义类引用不会触发此类的初始化:
A a[] = new A[];这样不会触发A类的初始化。
l 当访问一个静态域时,只有真正声明这个域的类才会初始化:
通过子类访问父类声明的静态域的时候,父类会初始化,但是子类不会初始化。
标签:
原文地址:http://www.cnblogs.com/chun-jiang-chao-de-gu-shi/p/5380586.html