类加载过程
类加载过程可以分为三步:加载->连接->初始化。
连接过程又可分为三步:验证->准备->解析。
加载这一步主要通过 类加载器 完成
什么是类加载器,类加载器有哪些?
类加载器会加载 Java 类的字节码( .class
文件)到 JVM 中,在内存中生成一个代表该类的 Class
对象
JVM 中内置了三个重要的类加载器:
BootstrapClassLoader
(启动类加载器):最顶层的加载类,由 C++实现,主要用来加载 JDK 内部的核心类库(%JAVA_HOME%/lib
目录下的rt.jar
、resources.jar
、charsets.jar
等 jar 包和类)。ExtensionClassLoader
(扩展类加载器):主要负责加载%JRE_HOME%/lib/ext
目录下的 jar 包和类。继承启动类加载器。AppClassLoader
(应用程序类加载器):面向用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。继承扩展类加载器。
除了这三种类加载器之外,开发者可以自定义类继承类加载器,实现自定义类加载规则。
什么是双亲委派模型?
在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回
如果一个类加载器收到了类加载的请求,它首先不会自己尝试加载这个类,而是把这请求委派给父类加载器去完成(调用父加载器 loadClass()
方法来加载类)
因此所有的加载请求都应该先传输到最顶层的启动类加载器中。只有当父类加载器返回自己无法完成这个加载请求时,子类加载器才会尝试自己去加载。如果子类加载器也无法加载这个类,那么它会抛出一个 ClassNotFoundException
异常。
JVM为什么采用双亲委派机制
通过双亲委派机制保证了 Java 程序的稳定运行,避免某一个类被重复加载。
如何打破双亲委派模型
重写 loadClass()
方法。
重写 loadClass()
方法之后,可以改变双亲委派模型的执行流程。
例如,子类加载器可以先自己尝试加载这个类,而不是优先委派给父类。