类加载过程

类加载分为三步: 1.加载: 将class文件字节码加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.Class 对象。 2.链接:将java类的二进制代码合并到jvm运行状态的过程 (1)验证: 确保加载的类信息符合JVM规范 (2)准备: 为static修饰的类变量分配没存并设置初始值 (3)解析: 虚拟机常量池的符号引用(常量名)替换为直接引用(地址)的过程 3.初始化:执行类构造器<clinit>() 方法的过程,类构造器<clinit>() 编译期间自动收集所有类变量赋值动作和静态代码块合并产生的。 当初始化一个类时,如果发现其父类还没有进行初始化,先初始化其父类。 什么时候发生类的初始化? 1. 类的主动引用: (1)main方法 (2)new 一个对象 (3)调用静态成员(除了final常量)和静态方法。 (4)反射调用 )(5)初始化一个类时,如果父类没有初始化,先初始化其父类。 类的被动引用:不会发生初始化 (1)当访问一个静态域时,只有真正声明这个域的类才会初始化。如 当通过子类引用父类的静态变量,不会导致子类初始化。 (2)通过数组定义类引用,不会触发此类的初始化。 (3)引用常量不会触发 因为常量在链接阶段已经放在常量池中    在创建java类的对象时,类中各成员的执行顺序: 1.父类静态成员和静态初始化快,按在代码中出现的顺序依次执行。 2.子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。 3. 父类的实例成员和实例初始化块,按在代码中出现的顺序依次执行。 4.执行父类的构造方法。 5.子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。 6.执行子类的构造方法。 7.静态初始化块只会执行一遍 示例:  
public static void main(String[] args) {
        Son s = new Son();
        s = new Son();
    }
}
class Parent {
    {
        System.out.println("parent中的初始化块");
    }
    static {
        System.out.println("parent中static初始化块");
    }
    public Parent() {
        System.out.println("parent构造方法");
    }
}
class Son extends Parent {
    {
        System.out.println("son中的初始化块");
    }
    static {
        System.out.println("son中的static初始化块");
    }
    public Son() {
        System.out.println("son构造方法");
    }

执行结果:

parent中static初始化块 son中的static初始化块 parent中的初始化块 parent构造方法 son中的初始化块 son构造方法 parent中的初始化块 parent构造方法 son中的初始化块 son构造方法   非静态初始化块主要是用于对象的初始化操作,在每次创建对象的时都要调用一次,其执行顺序在构造方法之前。      
上一篇:sentinelsat 多线程下载,提升下载速度(不支持断点续传)


下一篇:带你读《C语言程序设计教程 第4版》之一:C语言概述