JAVA ClassLoader - tenji/ks GitHub Wiki
JAVA 类加载器
什么是 ClassLoader?
我们知道 Java 程序在 Java 虚拟机(JVM)上运行。 当我们编译 Java 类时,它将以字节码的形式进行转换,该字节码是平台和机器独立编译的程序,并将其存储为.class文件。 之后,当我们尝试使用 Class 时,Java ClassLoader 会将该类加载到内存中。
Java 中有三种类型的内置 ClassLoader:
- Bootstrap Class Loader - 它加载 JDK 内部类,通常加载
rt.jar
和其他核心类,例如java.lang.*
包下的类。 - Extensions Class Loader - 它从 JDK 扩展目录加载类,通常是
$JAVA_HOME/lib/ext
目录。 - System Class Loader - 它从当前类路径加载类,该类可以在使用
-cp
或-classpath
命令行选项调用程序时进行设置。
Java ClassLoader 是分层的,每当引发一个请求来加载一个类时,它就会将它委派给它的父类加载器,并以这种方式在运行时环境中保持唯一性。 如果父类加载器没有找到该类,那么类加载器本身会尝试加载该类。
package com.journaldev.classloader;
public class ClassLoaderTest {
public static void main(String[] args) {
System.out.println("class loader for HashMap: "
+ java.util.HashMap.class.getClassLoader());
System.out.println("class loader for DNSNameService: "
+ sun.net.spi.nameservice.dns.DNSNameService.class
.getClassLoader());
System.out.println("class loader for this class: "
+ ClassLoaderTest.class.getClassLoader());
System.out.println(com.mysql.jdbc.Blob.class.getClassLoader());
}
}
上面的 Java Classloader 示例程序的输出是:
class loader for HashMap: null
class loader for DNSNameService: sun.misc.Launcher$ExtClassLoader@7c354093
class loader for this class: sun.misc.Launcher$AppClassLoader@64cbbe37
sun.misc.Launcher$AppClassLoader@64cbbe37
正如你所看到的那样,java.util.HashMap ClassLoader 的输出是 null,它反映了 Bootstrap ClassLoader,而 DNSNameService ClassLoader 是 ExtClassLoader。 由于 ClassLoaderTest 类本身在 CLASSPATH 中,因此 System ClassLoader 会加载它。
ClassLoader继承体系
JAVAEE 委派模型
为什么需要自定义 ClassLoader?
Java默认的 ClassLoader 可以从本地文件系统加载文件,这已经可以满足大多数的情况。 但是如果你需要在运行时、从FTP服务器、通过第三方 WEB 服务加载类的话,则必须扩展现有的类加载器。 例如,AppletViewers
从远程 WEB 服务器加载类。
如何自定义 ClassLoader?
常见问题及分析
Java EE 委托模型可能会导致一些有趣的类加载问题。 NoClassDefFoundError
,LinkageError
,ClassNotFoundException
,NoSuchMethodError
,ClassCastException
等是开发Java EE应用程序时遇到的非常常见的异常。 我们可以对这些问题的根本原因做出各种假设,但验证我们的假设非常重要,以便我们遇到此类问题时不会束手无策。
NoClassDefFoundError
NoClassDefFoundError
是开发 Java EE 应用程序时可能遇到的最常见问题之一。根本原因分析和解决过程的复杂性主要取决于 Java EE 中间件环境的大小;尤其是考虑到各种 Java EE 应用程序中存在大量的类加载器。