java 中类加载器
Posted zeenzhou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 中类加载器相关的知识,希望对你有一定的参考价值。
jar 运行过程和类加载机制有关,而类加载机制又和我们自定义的类加载器有关,现在我们先来了解一下双亲委派模式。
java 中类加载器分为三个:
-
BootstrapClassLoader 负责加载
$JAVA_HOME/jre/lib
部分 jar 包 -
ExtClassLoader 加载
$JAVA_HOME/jre/lib/ext
下面的 jar 包 -
AppClassLoader 加载用户自定义 -classpath 或者 Jar 包的 Class-Path 定义的第三方包
类的生命周期为:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using) 和 卸载(Unloading)七个阶段。
当我们执行 java -jar 的时候 jar 文件以二进制流的形式被读取到内存,但不会加载到 jvm 中,类会在一个合适的时机加载到虚拟机中。类加载的时机:
-
遇到 new、getstatic、putstatic 或 invokestatic 这四条字节码指令时,如果类没有进行过初始化,则需要先对其进行初始化。这四条指令的最常见的 Java 代码场景是使用 new 关键字实例化对象的时候,读取或设置一个类的静态字段调用一个类的静态方法的时候。
-
使用 java.lang.reflect 包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
-
当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
-
当虚拟机启动时,用户需要指定一个要执行的主类(包含 main() 方法的那个类),虚拟机会先初始化这个主类。
当触发类加载的时候,类加载器也不是直接加载这个类。首先交给 AppClassLoader
,它会查看自己有没有加载过这个类,如果有直接拿出来,无须再次加载,如果没有就将加载任务传递给 ExtClassLoader
,而 ExtClassLoader
也会先检查自己有没有加载过,没有又会将任务传递给 BootstrapClassLoader
,最后 BootstrapClassLoader
会检查自己有没有加载过这个类,如果没有就会去自己要寻找的区域去寻找这个类,如果找不到又将任务传递给 ExtClassLoader
,以此类推最后才是 AppClassLoader
加载我们的类。这样做是确保类只会被加载一次。通常我们的类加载器只识别 classpath (这里的 classpath 指项目根路径,也就是 jar 包内的位置)下 .class
文件。jar 中其他的文件包括 jar 包被当做了资源文件,而不会去读取里面的 .class
文件。但实际上我们可以通过自定义类加载器来实现一些特别的操作
以上是关于java 中类加载器的主要内容,如果未能解决你的问题,请参考以下文章
java中类加载器ClassLoader,双亲加载机制,启动类加载器,应用类加载器,线程上下文类加载器