这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战」
一个class的生命周期分为四步:
loading、linking、initalizing、被GC回收。
其中一个class变成完全状态
是需要经过loading、linking、initalizing三步
Loading
Loading就是把一个class加载到内存的过程。
在java中,是通过一种叫做ClassLoader的类进行对类的加载工作的。
ClassLoader是一个顶级父类,针对这个类,有多种类型的子类。 在这些类型中,有一个顶级的类加载器,叫做Bootstrap ClassLoader,它是由C++实现的,负责加载java中的核心库,也因此它在java中并没有对应的对象类型,所以每当想要获得它的时候,都会得到null值。 Bootstrap ClassLoader不但会加载所有核心类库,还负责将除它之外的所有其他类型的ClassLoader进行加载。 其他类型ClassLoader分为三种:
-
Extension ClassLoader 负责加载java扩展包里的class文件
-
App ClassLoader 负责加载用户创建的class文件,一般我们写的指定的classpath下的class就都是由它进行加载的。
-
Custom ClassLoader ,除了上述几种之外,用户还可以继承ClassLoader接口,来实现自己的一套加载类的逻辑,这种都属于自定义的classloader
可以查看一下例子
public class ClassLoaderTest001 {
public static void main(String[] args) {
//加载java核心包的classloader
System.out.println(String.class.getClassLoader());
//加载java核心包的classloader
System.out.println(sun.awt.HKSCS.class.getClassLoader());
//加载扩展包里的classloader
System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());
//当前这个类的classloader
System.out.println(ClassLoaderTest001.class.getClassLoader());
//加载扩展包里的classloader的classloader
System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader().getClass().getClassLoader());
//加载当前类的classloader的classloader
System.out.println(ClassLoaderTest001.class.getClassLoader().getClass().getClassLoader());
}
}
打印结果如下:
null //为空,说明是Bootstrap ClassLoader
null //为空,说明是Bootstrap ClassLoader
sun.misc.Launcher$ExtClassLoader@45ee12a7 //ExtClassLoader
sun.misc.Launcher$AppClassLoader@18b4aac2 //AppClassLoader
null //为空,说明是Bootstrap ClassLoader 验证了除Bootstrap ClassLoader之外的ClassLoader的都是由Bootstrap ClassLoader进行加载的
null //为空,说明是Bootstrap ClassLoader 验证了除Bootstrap ClassLoader之外的ClassLoader的都是由Bootstrap ClassLoader进行加载的
各个 ClassLoad 它们之间的关系并不存在继承关系
那是什么关系把它们连接起来的?
它们是存在引用关系的。
也就是自下向上,自定义类加载器有个parent指向App加载器,App加载器有个parent指向Ext加载器,Ext加载器有个parent指向Bootstrap加载器
package jacquesh.jvm.study.classload;
public class ClassLoaderTest002 {
public static void main(String[] args) {
//加载当前类的classloader的classloader
System.out.println(ClassLoaderTest002.class.getClassLoader().getClass().getClassLoader());
//加载当前类的classloader的parent
System.out.println(ClassLoaderTest002.class.getClassLoader().getParent());
}
}