类加载器与双亲委派模型
前言:类加载流程
关于类加载流程,详细内容可以参考我的上一篇文章。此处简要总结下。
类加载分为加载-链接-初始化三个阶段:
加载:将class文件二进制字节码数据读入jvm的方法区,在堆中生成对应class对象。
链接:验证字节信息符合jvm规范,初始化静态变量初始值,将常量池中符号引用替换为直接引用。
初始化:执行类初始化逻辑,即
clinit
方法,包括静态变量赋值动作,静态代码块。
本文讨论的类加载器ClassLoader,在加载阶段将 class 的字节码转换成class对象。
类加载器
启动类加载器(Bootstrap Class-Loader),加载 jre/lib 下面的 jar 文件,如 rt.jar。常用内置库 java.xxx.* 都在里面,如 java.util.*、java.io.*、java.nio.*、java.lang.* 等
扩展类加载器(Extension or Ext Class-Loader),负责加载我们放到 jre/lib/ext/ 目录下 面的 jar 包
应用类加载器(Application or App Class-Loader),加载 Classpath 环境变量里定义的路径中的 jar 包和目录,也是系统类加载器。
双亲委派模型:
定义:简单说就是当类加载器(Class-Loader)试图加载某个类型的时候, 除非父加载器找不到相应类型,否则尽量将这个任务代理给当前加载器的父加载器去做。
双亲委派模型的好处:
安全性,避免用户自己编写的类动态替换 Java的一些核心类,比如 java.lang.String。
唯一性 避免类的重复加载。因为 JVM中区分不同类,不仅仅是根据类名,相同的 class文件被不同的 ClassLoader加载就是不同的两个类。
自定义类加载器
注意的地方:
Obj.class文件不能放在classpath路径下。因为双亲委派模型父类会先加载,如果在父类类加载器路径下,则会由父类进行加载。
重写ClassLoader类中findClass()方法。通过类全限定名找到字节码文件转为字节数组,在将数组转换为class对象。
Last updated
Was this helpful?