ClassLoader
1、Java程序如何运行
一个Java程序的运行整个过程分为编译时和运行时。首先原始的java程序先由java编译器javac来编译成字节码,即.class文件,然后有ClassLoader类加载器加载类的常量、方法等到内存,字节码校验器对变量初始化、方法调用、堆栈溢出等进行校验,如果校验没问题,就会交给执行引擎解释执行最终生成机器码给操作系统执行。
2、了解ClassLoader工作机制
我们已经知道ClassLoader是负责加载类,那么到底怎么去加载?
学习这篇文章https://juejin.im/post/6844903729435508750 ,总算弄懂ClassLoader怎么运作的。
JVM 中内置了三个重要的 ClassLoader,分别是 BootstrapClassLoader、ExtensionClassLoader 和 AppClassLoader。
BootstrapClassLoader 负责加载 JVM 运行时核心类,这些类位于 $JAVA_HOME/lib/rt.jar 文件中【rt是runtime的简写】,我们常用内置库 java.xxx.* 都在里面,比如 java.util.、java.io.、java.nio.、java.lang. 等等。
ExtensionClassLoader 负责加载 JVM 扩展类,比如 swing 系列、内置的 js 引擎、xml 解析器 等等,这些库名通常以 javax 开头,它们的 jar 包位于 $JAVA_HOME/lib/ext/*.jar 中,有很多 jar 包。
AppClassLoader 才是直接面向我们用户的加载器,它会加载 Classpath 环境变量里定义的路径中的 jar 包和目录。我们自己编写的代码以及使用的第三方 jar 包通常都是由它来加载的。
双亲委派:AppClassLoader 在加载一个未知的类名时,它并不是立即去搜寻 Classpath,它会首先将这个类名称交给 ExtensionClassLoader 来加载,如果 ExtensionClassLoader 可以加载,那么 AppClassLoader 就不用麻烦了。否则它就会搜索 Classpath 。而 ExtensionClassLoader 在加载一个未知的类名时,它也并不是立即搜寻 ext 路径,它会首先将类名称交给 BootstrapClassLoader 来加载,如果 BootstrapClassLoader 可以加载,那么 ExtensionClassLoader 也就不用麻烦了。否则它就会搜索 ext 路径下的 jar 包。这三个 ClassLoader 之间形成了级联的父子关系,每个 ClassLoader 都很懒,尽量把工作交给父亲做,父亲干不了了自己才会干。每个 ClassLoader 对象内部都会有一个 parent 属性指向它的父加载器。
UserDefined ClassLoader: 这是开发人员通过拓展ClassLoader类定义的自定义加载器,加载程序员定义的一些类。
参考链接:
https://yq.aliyun.com/articles/623212