Java类加载过程

一.类加载过程简介

类的加载一般分为三个比较大的阶段,分别是加载阶段、连接阶段和初始化阶段。

1.加载阶段

  主要负责查找并且加载类的二进制数据文件,其实就是class文件

2.连接阶段

  连接阶段所做的工作比较多,主要分为以下三个阶段:

(1)验证阶段

     主要是保证确保类的正确性,譬如class文件的版本,class文件的魔术因子是否正确。

(2)准备阶段

     为类的静态变量分配内存,并且为其初始化默认值。

(3)解析阶段

     把类中的符号引用转换成直接引用。

  1. 初始化阶段

       为类的静态变量赋予正确的初始值也就是代码编写阶段给定的值。

一.ClassLoader介绍

ClassLoader 的主要职责是负责加载各种class文件到JVM中,ClassLoader是一个抽象的class,给定一个class的二进制文件名,ClassLoader会尝试加载并且在JVM中生成构成这个类的各个数据结构,然后使其分布在JVM对应的内存区域中。

二.类的主动使用和被动使用

        JVM虚拟机规范规定,每个类或者接口被Java程序首次主动使用时才会对其进行初始化,但是不排除JVM在运行期间提前预判并且初始化某个类。

JVM同时规范了以下6中主动使用类的场景,具体如下:

(1)通过new关键字会导致类的初始化,并且是最终的初始化。

(2)访问类的静态变量,包括读取和更新会导致类的初始化。

public class Simple {
	static{
		System.out.println("初始化");
	}
	public static int x = 10;
}

以上代码中直接访问变量x也会导致类的初始化。

(3)访问类的静态方法,会导致类的初始化。

public class Simple {
    static{
        System.out.println("初始化");
    }
    public static int x = 10;
    
    //静态方法
    public static void test(){
        
    }
}

以上代码中直接调用test静态方法也会导致类的初始化。

(4)对某个类进行反射操作,会导致类的初始化。

(5)初始化子类会导致父类的初始化,通过子类使用父类的静态变量,只会导致父类的初始化,子类则不会被初始化。

(6)启动类,也就是执行main函数所在的类会导致该类的初始化。

 

除了以上的6种情况,其余的都称为被动使用,不会导致类的加载和初始化。

(1)构造某个类的数组时并不会导致该类的初始化。

Simple[] simples = new Simple[10];
System.out.println(simples.length);

(2)引用类的静态常量不会导致类的初始化。

public final static int MAX = 100;

 

 

posted @ 2019-04-05 16:37  深蓝---Jack  阅读(221)  评论(0编辑  收藏  举报