「JVM 类加载子系统」系列文章
加载阶段需要完成的一个核心任务:「通过一个类的全限定名来获取定义此类的二进制字节流」
Java 虚拟机设计团队有意将这一任务放到 Java 虚拟机外部,以便让应用程序自己去决定如何获取所需的类
实现这个任务的代码就被作:类加载器
类加载器虽然只用于完成实现类的加载动作,但它在 Java 程序中起到的作用却远超类加载阶段
每个 Class 对象都有一个方法:getClassLoader()。顾名思义,获取加载该 Class 对象的类加载器
对于任意一个类,都必须由它的类加载器和这个类本身一起共同确定它在 Java 虚拟机中的唯一性
更通俗一点:比较两个类是否「相等」,只有在这两个类是由同一个类加载器加载的前提下才有意义;否则,即使这两个类来源同一个 Class 文件,被同一个 Java 虚拟机加载,只要加载它们的类加载器不同,那么这两个类就必定不相等
从 Java 虚拟机的角度,只有两种不同的类加载器:
java.lang.ClassLoader从 Java 开发人员的角度,类加载器的划分更细致一些:
启动类加载器 (Bootstrap ClassLoader):负责加载存放在<JAVA_HOME>/lib目录,或者被-Xbootclasspath参数所指定的路径中存放的,而且可以被 JVM 识别的类库加载到虚拟机内存中
rt.jar、tools.jar,名字不符合的类库即使放在lib目录中也不会被加载扩展类加载器 (Extension ClassLoader):负责加载存放在<JAVA_HOME>/lib/ext目录,或者被java.ext.dirs系统变量所指定的路径中所有的类库
sun.misc.Launcher$ExtClassLoader中以 Java 代码的形式实现应用程序类加载器 (Application ClassLoader):负责加载用户类路径 (ClassPath) 上所有的类库
sun.misc.Launcher$ClassLoader中以 Java 代码的形式实现它们三者的关系如下:(增加了一个自定义类加载器)
xxxxxxxxxxpublic static void main(String[] args) { ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); System.out.println(systemClassLoader.getParent()); System.out.println(systemClassLoader.getParent().getParent());}// resultsun.misc.Launcher$AppClassLoadersun.misc.Launcher$ExtClassLoadernull由于启动类加载器是由 C++ 实现,所以只会输出一个null
关于三者的源码分析可见 剖析 [Bootstrap、Extension、Application] ClassLoader
下面可以更具体的输出一下每个类加载器加载的类库
public static void main(String[] args) { System.out.println("---- 启动类加载器加载的文件 ----"); URL[] urLs = Launcher.getBootstrapClassPath().getURLs(); for (URL urL : urLs) { System.out.println(urL); } System.out.println("---- 扩展类加载器加载的文件 ----"); System.out.println(System.getProperty("java.ext.dirs")); System.out.println("---- 应用程序类加载器加载的文件 ----"); System.out.println(System.getProperty("java.class.path"));}
---- 启动类加载器加载的文件 ----file:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/resources.jarfile:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/rt.jarfile:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/sunrsasign.jarfile:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jsse.jarfile:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jce.jarfile:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/charsets.jarfile:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jfr.jarfile:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/cat.jarfile:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/classes---- 扩展类加载器加载的文件 ----/Users/lfool/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java---- 应用程序类加载器加载的文件 ----/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/cat.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/crs-agent.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/legacy8ujsse.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/openjsse.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/rt.jar:/Users/lfool/myself/IdeaProjects/concurrency/target/classes:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar