Java中类的加载过程
类加载的过程:
1、加载:通过类加载器把字节码加载到方法区中,生成一个对应的Class对象。
2、链接:分配内存,连接引用。
3、初始化:先初始化父类,在初始化自己。(执行类的构造器:< clinit( ) > 方法)
1、加载
类加载器( abstract class ClassLoader)
引导类加载器:BootClassLoader。用来加载Java的核心库。用C语言实现,它并未实现java.lang.ClassLoader。
扩展类加载器:ExtClassLoader,它继承了BootClassLoader。用来加载Java扩展库。
应用程序加载器:AppClassLoader,它继承了ExtClassLoader。根据路径进行加载类。
以上采用代理模式加载(双亲委派机制),在加载时会先由父类进行加载,父类加载失败再自己加载,例如:
我需要加载一个用户自己编写的java.lang.String类,AppClassLoader会丢给ExtClassLoader加载,ExtClassLoader会丢给BootClassLoader加载。显然这个类会在父类加载器中加载,也就是说用户自己编写的String将不会被加载。
常用方法:
ClassLoader.getSystemClassLoader() 获取系统使用的类加载器
getParent() 获取此加载器的父类加载器。
loadClass(String name) 加载名称为name的类,返回Class对象。
findClass(Stirng name) 查找名称为name的类,返回Class对象。
可以通过继承ClassLoader自定义类加载器自定义类加载器。
2、链接
1、验证:验证加载的类符合JVM规范,可以加载。
2、准备:为static变量分配内存(方法区),赋初始值。
3、解析:常量池内的符号引用替换为直接引用。
3、初始化
1、初始化一个类,如果其父类未初始化,会先初始化它的父类。
2、初始化过程是执行类的构造器:< clinit( ) > 方法,此方法由编译器自动收集的“类中所有静态变量的赋值语句+静态块”得到,编译器的收集顺序由代码的出现顺序决定,所以静态块只能访问前面的静态变量,不能访问后面的静态变量。
不会导致类的初始化:1、引用类中的常量。2、通过数组定义类的引用。
jvm简易结构