Java类的加载,连接和运行过程

来源:互联网 发布:淘宝买家旺旺号是什么 编辑:程序博客网 时间:2024/04/30 19:55

希望大家对java的学习不用仅仅停留在api的调用上,要对内部运行机制有一定的了解。

类的加载 连接和运行

当程序主动使用某个类时,如果该类还未被加载到内存中,系统会通过加载,连接,初始化三个步骤来对该类进行初始化,JVM会完成这三个步骤,有时我们也讲这三个步骤统称为类的加载或初始化。

  1. 类的加载  类的加载是指类的class文件读入内存中,并为之创建java.lang.Class类的一个对象。也就是说当程序中使用任何的类时系统都会会值建立一个java.lang.Class类对象。这在java反射机制中会遇到。
  2. 类的连接  当类被加载后,系统为之生成一个对应地Class对象,接着将会进入连接阶段。连接阶段将会负责把类的二进制数据合并到JRE中,类的连接分为三个阶段:验证:用于验证被加载的类是否有正确的内部结构。准备:类准备阶段负责为类的静态属性分配内存,并为之设置默认初始值。解析:将类的二进制数据中的符号引用替换为直接引用。
  3. 类的初始化 在类的初始化阶段 虚拟机负责对类进行初始化,主要是对静态属性进行初始化。Java类中队静态属性指定初始值有两种方式:声明静态属性时指定初始化值;使用静态初始化块为静态属性指定初始值。
JVM初始化一个类包含如下步骤:

  1. 假如这个类还没有被加载和连接,则先加载和连接该类
  2. 假如该类有直接的父类还没有被初始化,则初始化其直接父类。
  3. 假如类中有初始化语句,则系统异常执行这些初始化语句。
下面介绍一下java中的静态初始化块
static{}
(当Java创建一个对象时,系统先为对象的说有实例属性分配内存,当然前提是该类已经加载过。接着为这些属性初始化,其初始化的顺序为:先执行初始化块或声明属性时指定的初始值,再执行构造方法里指定的初始值)
静态初始化块是类相关的。系统将在类初始化阶段执行静态初始化块,而不是在创建对象时才执行,所以静态初始化块要比普通初始化块先执行。
如下面的例子:

class A{static{   System.out.println("A中静态初始化块");}{System.out.println("A中普通初始化块");}public A(){System.out.println("A中无参构造方法");}}class B extends A{static{   System.out.println("B中静态初始化块");}{System.out.println("B中普通初始化块");}public B(){System.out.println("B中无参构造方法");}public B(String msg){this();System.out.println("B中有参构造方法");}class C extends B{static{   System.out.println("C中静态初始化块");}{System.out.println("C中普通初始化块");}public C(){super("xuan");System.out.println("C中无参构造方法");}}public class Test{public static void main(String[] args){new C();new C();}}
分析:第一次创建一个C对象时,因为还未加载C类,因此需要先加载并初始化C类。初始化C类时先执行期最顶层父类的静态初始化块,再执行其直接父类的静态初始化块,最后初始化本身的静态初始化块。当C类已经初始化后,C类在JVM中会一直存在,因此第二次在创建C类对象时不再对C类进行初始化。而是对对象实例进行初始化,每次创建一个对象时都需要先执行最顶层父类的初始化块和构造方法,然后是父类的初始化块和构造方法,以此类推。最后执行自己的初始化块和构造方法。

原创粉丝点击