• 类加载器


    1.  概述

      虚拟机把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,这个动作的代码模块称为类加载器。

    2.  类与类加载器

      对于任意一个类,都需要加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性。

      比较两个是否相等只有在同一个类加载器的前提下才有意义,

      对于同一个class文件,如果他们的类加载器不同,那这两个类就必定不相等。

    3.  类加载器

    3.1 启动类加载器(Bootstrap ClassLoder)

      这个类负责将存放在<JAVA_HOME>lib目录下,并且是虚拟机识别(仅按照文件名识别,如rt.jar,名字不符合的类库不会被加载)的类库加载到虚拟机内存中,启动类加载器无方法被Java程序直接引用。

    3.2 扩展类加载器(Extension ClassLoder)

      该类加载器由 sun.misc.Launcher$ExtClassLoder 实现,负责加载<JAVA_HOME>libext目录下的,或者被 java.ext.dirs 系统变量所指定的所有类库,开发者可直接使用扩展类加载器。

    3.3 应用程序类加载器(Application ClassLoder)

      该类加载器由 sun.misc.Launcher$AppClassLoder 实现,该类加载器是ClassLoder中getSystemClassLoder()的返回值,负责加载用户路径(ClassPath)下指定的类库一般情况下这个就是默认的类加载器。

    3.4 自定义类加载器

      通过继承 ClassLoader ,然后重写findClass()方法自定义类加载器

    4. 双亲委派模型

      

    4.1 工作原理  

      如果有一个类加载器收到以一个类加载的请求,它先把这个请求委派给父类去完成,当父类无法完成这个加载请求时,子类才会尝试自己去加载这个类。

      Java 类随着它的类加载器一起具备了一种带有优先级的层次关系,保证Java体系中最基础的行为。

    4.2 作用

      保证核心类库在内存中的唯一性。

      如果用户自定义了一个Object类,由于引导类加载器已经加载了这个类,则直接返回已经加载的类,而不会继续加载这个类。

      

    public class String {
    
        public static void main(String[] args) {
            System.out.println(123);
        }
    }

      自定义一个String类,并编写main方法,运行后报错如下:

      

       虚拟机加载的是jdk自带的String类,然而String 类没有main方法,所以报错。

    5. 破坏双亲委派模型

      1. JDK在1.2之后引入双亲委派模型,为了向前兼容,java.lang;ClassLoder添加了一个protected 的 findClass(), 用于实现自定义的类加载

      2. Java提供的一些服务需要调用第三方的代码,引入线程上下文类加载器(Thread Context ClassLoder)。该类加载器通过 java.lang.Thread 类的 setContextClassLoader() 进行设置。默认为应用程序类加载器。

      该过程中父类加载器请求子类加载器完成类加载请求。

      Java中定义了java.sql.Driver接口,但是其实现是由各个厂商来实现,Driver接口是在rt.jar中,本来应该有引导类加载器加载,实际上是通过线程上下文类加载器来加载其具体实现的。

  • 相关阅读:
    mysql之drop、truncate和delete的区别
    mysql之表结构,表空间,段,区,页,MVCC(待整理)
    mysql之子查询、视图、事务及pymysql等
    mysql之单表查询、多表查询
    解决跨域问题!
    项目--2
    项目--1
    后端接口书写
    VUE-组件
    VUE基本写法
  • 原文地址:https://www.cnblogs.com/virgosnail/p/9610047.html
Copyright © 2020-2023  润新知