从运行结果可以看出来,JVM 首先 Load 进来的是 Object 类,然后 load 一些核心类
或接口。比如 System 类,String 类,Serializable 接口等,接着开始 load 我们自定的
TestClassLoader 类,进入 main 方法后,JVM 依次 load 了 A、B、C、D 类。加载完 A
后,打印“after load A”再加载 B,说明类是动态加载,需要时才加载。“invoke C static
block”打印一次,说明静态初始化语句块只在类加载后才调用,且只调用一次。“invoke
D init block”打印两次,说明初始化语句块在每次实例化对象时就会被调用。
3、JDK 内置 ClassLoader
JVM 本身包含了一个 ClassLoader 称为 Bootstrap ClassLoader,和 JVM 一样,
Bootstrap ClassLoader 是用本地代码实现的,它负责加载核心 Java Class(即所
有 java.*开头的类)。另外 JVM 还会提供两个 ClassLoader,它们都是用 Java 语言
编写的,由 Bootstrap ClassLoader 加载;其中 Extension ClassLoader 负责加载
扩展 的 Java class ( 例如 所有 javax.* 开头 的类 和 存放 在 JRE 的 ext 目 录下 的 类),
Application ClassLoader 负责加载应用程序自身的类。如下表:
Class loader 类型 用途
bootstrap class loader
用本地语言实现如:汇编,C 或 C++
用于加载 jdk 的核心类
extesion class loader
加载 jre/lib/ext 中的类
applicaon class loader
加载自定义类
ClassLoader.getSystemClassLoader()
other class loader SecureClassLoader
URLClassLoader
以下代码显示了不同类的是类加载器
package com.puckasoft.reflect;
public class TestJDKClassLoader {
public static void main(String[] args) {
System.out.println("String的类加载器是:" +
String.class.getClassLoader());
System.out.println("JDK_HOME\\jre\\lib\\ext\\
sunjco_provider.
jar中的AESCipher的类加载器:"+com.sun.crypto.provider
.AESCipher.class.getClassLoader().getClass().getName());
System.out.println("自定义类TestJDKClassLoader的类加载器是:"
+ TestJDKClassLoader.class.getClassLoader().getClass()
.getName());
}
}