Java虚拟机 双亲委派机制 的工作原理

程序员考拉

共 1431字,需浏览 3分钟

 ·

2020-11-07 15:09


类的加载:


加载指的是将类的class文件读入到内存,并为之创建一个java.lang.Class对象,也就是说,当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象。


类的加载由类加载器完成,类加载器通常由JVM提供,这些类加载器也是前面所有程序运行的基础,JVM提供的这些类加载器通常被称为系统类加载器。除此之外,开发者可以通过继承ClassLoader基类来创建自己的类加载器。


双亲委派机制 的工作原理


1)如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行。


2)如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归请求最终将到达顶层的启动类加载器。


3)如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。



案例举例:


下面我们不妨通过一个例子来帮助我们理解一下双亲委派机制:


首先我们在工程下创建一个java.lang包,包下新建一个String类(我们在此只做示范,实际代码中不推荐同学们以此命名)



在String类中加入以下代码:


package java.lang;

public class String {
  static {
    System.out.println("我是java.lang包下的String类");
  }
}


我们可以将其看成一个我们手写的一个”伪装“的String类


接着我们在工程的另一个包下新建一个StringTest类



其中加入以下方法:


package Test;

public class StringTest {
  public static void main(String[] args) {
    String str=new java.lang.String();
    System.out.println("开始测试。。。");
  }
}


那么问题来了,当我们new java.lang包下的String类时,我们new的是java系统包下的String呢还是我们刚刚自己定义的String类呢?


换言之,我们在上面定义的String类中加入的static静态代码块会不会执行呢??


请看运行结果:



很显然,static静态代码块并没有执行,我们new 的String类仍是系统包下的String类。


案例解析:


这便是双亲委派机制的完美体现。很好保证了我们系统核心API不容易被破坏。


当我们new String时,我们自己创建的String类应当由系统类加载器(应用程序类加载器)来加载,但根据双亲委派机制,系统类加载器会先委托给它的父类加载器(拓展类加载器)去加载,如果拓展类加载器仍存在父类则继续向上委托。


我们 new String时向上委托会被引导类加载器(BootStap ClassLoader)所加载,所以我们new 出的String便是我们核心API中的String类,即不会再new我们自己创建的String类。


双亲委派机制的优势:


1)避免类的重复加载


2)保护程序安全,防止核心API被随意篡改




浏览 13
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报