JUC与JVM(4)类加载器

JVM(1)类加载器

在这里插入图片描述
JVM位置:
在这里插入图片描述

jvm是运行在操作系统之上的;它和硬件没有直接交互;

JVM架构体系:在这里插入图片描述

类加载器 Class loader

负责加载class文件(java -c编译的java文件),class文件在文件开头有特定的文件标示(class文件由开头,作为校验,判断该文件是否合法),将class文件字节码内容加载到内存中,并将这些内容转换成方法区中—运行时数据结构,并且class loader只负责class文件的加载,至于它是否运行,由Executiong engine决定;

在这里插入图片描述
类加载器可以想为快递员,把小class文件,加载并初始化成为java.lang.Class(反射的时候得到的该对象,又称为字节码对象)(即进入内存);随后实例化成为jvm堆内存中的对象;

类加载器分类
  1. 虚拟机自带的类加载器
    1. 启动类加载器BootstrapClassLoader;C++
    2. 拓展类加载器ExtensionCLassLoader;Java
    3. 应用程序类加载器ApplicationClassLoader;(亦称系统类加载器)
  2. 用户自定义类加载
    1. java.lang.ClassLoader的子类;用户可以定制的类加载器;
不同类加载对应的作用

在这里插入图片描述

public class MyObject {
    public static void main(String[] args) throws ClassNotFoundException {
        Object o = new Object();
        System.out.println(o.getClass().getClassLoader());//null
        MyObject myObject = new MyObject();
        sun.misc.Launcher$AppClassLoader@18b4aac2
        System.out.println(myObject.getClass().getClassLoader());
    }
}

因BootstrapClassLoader为C++语言编写,故此时输出为null;Object这个包载哪儿呢?

​ 1. Object的class文件位于java/jre/lib/rt.jar内,故由上图可知,BootsrapClassLoader加载jvm所需的运行环境

而自己编写的类由ApplicationClassLoader进行加载,输出为sun.misc.Launcher$AppClassLoader@18b4aac2;

那么sun.misc.Launcher是什么呢?查看rt.jar在该路径下sun/misc/Launcher.class,这是一个启动类–入口程序;

那么ExtensionCLassLoader加载什么呢?在java/jre/lib/ext内还有许多jar包,随着java的升级,该类加载器可用于更好的拓展java,故此类加载器是用于加载java/jre/lib/ext内的jar包的;

分析以下输出结果:

public class MyObject {
    public static void main(String[] args) throws ClassNotFoundException {
        Object o = new Object();
        //java.lang.NullPointerException
        //System.out.println(o.getClass().getClassLoader().getParent());
        MyObject myObject = new MyObject();
      	sun.misc.Launcher$AppClassLoader@18b4aac2
        System.out.println(myObject.getClass().getClassLoader());
        //sun.misc.Launcher$ExtClassLoader@61bbe9ba
        System.out.println(myObject.getClass().getClassLoader().getParent());
        //null
	      System.out.println(myObject.getClass().getClassLoader().
                         getParent().getParent());
    }
}

可知类加载器也父子关系:层级如上图所示

双亲委派机制

创建java.lang的package,同时创建String类,

public class String {
    public static void main(String[] args) throws ClassNotFoundException {
        System.out.println("test");
    }
}

运行报错:在java.lang.String中找不到main方法;实际运行的是JDK的String类;同时该段代码能通过编译;

原因解析如下:

​ 在运行自定java.lang.String类时,即ApplicationClassLoader运行,不查找直接向往上,到ExtCLassLoader,不查找,直接找父亲,BootstrapClassLoader,找到了jdk的String类;

双亲委派:当一个类收到了类加载的请求时,它首先不会尝试去处理这个类,而是把这个请求委派给它的父类,每一层的类加载器都是如此,当父类无法完成该请求时(该父类的加载路径下无该类),该子类才会尝试自己加载;

意义:不污染java的源代码,从顶级父类开始查找;(健壮性);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值