1.类的加载器:
- 启动类加载器:由c++语言实现,负责加载Java中的核心类
- 扩展类加载器:负责加载Java中核心类之外的类
- 应用程序类加载器:负责加载用户类路径上指定的类库
2.委派模型(由低到高):
自定义类加载器→应用程序类加载器→扩展类加载器→启动类加载器
双亲委派模型要求除了顶层的启动类加载器之外,其他类加载器都要有父类,通过组合实现
3.双亲委派模型的工作流程/原理:
简单说:
当一个类加载的任务来临的时候,先交给父类加载器完成,知道传递给启动类加载器,如果完成不了的情况下,再依次往下传递类加载的任务。
详细解释:
如果一个类收到了类加载的请求,它并不会自己先去加载,而是把这个请求委托给父类加载
器去执行,如果父类加载器还存在父类加载器,则进一步向上委托,依次递归,请求最后到
达顶层的启动类加载器,如果父类能够完成类的加载任务,就会成功返回,倘若父类加载器
无法完成任务,子类加载器才会尝试自己去加载,这就是双亲委派模式。就是每个儿子都很
懒,遇到类加载的活都给它爸爸干,直到爸爸说我也做不来的时候,儿子才会想办法自己去
加载。
4双亲委派模型的优势?这样设计的原因?
简单说:
双亲委派模型能够保证Java 程序的稳定运行,不同层次的类加载器具有不同优先级,所有
的对象的父类 Object,无论哪一个类加载器加载,最后都会交给启动类加载器,保证安全。
详细解释:
采用双亲委派模式的好处就是Java类随着它的类加载器一起具备一种带有优先级的层次关
系,通过这种层级关系可以避免类的重复加载,当父亲已经加载了该类的时候,就没有必要
子类加载器(ClassLoader)再加载一次。其次是考虑到安全因素,Java核心API中定义类型
不会被随意替换,假设通过网路传递一个名为java.lang.Integer 的类,通过双亲委派的的模
式传递到启动类加载器,而启动类加载器在核心JavaAPI发现这个名字类,发现该类已经被
加载,并不会重新加载网络传递过来的java.lang.Integer而之际返回已经加载过的
Integer.class,这样便可以防止核心API库被随意篡改。可能你会想,如果我们在calsspath
路径下自定义一个名为java.lang.SingInteger?该类并不存在java.lang 中,经过双亲委托模式
传递到启动类加载器中,由于父类加载器路径下并没有该类,所以不会加载,将反向委托给
子类加载器,最终会通过系统类加载器加载该类。