Java虚拟机JVM学习05 类加载器的父委托机制
Java虚拟机JVM学习05 类加载器的父委托机制
类加载器
类加载器用来把类加载到Java虚拟机中。
类加载器的类型
有两种类型的类加载器:
1.JVM自带的加载器:
根类加载器(Bootstrap)
扩展类加载器(Extension)
系统类加载器(System)
2.用户自定义的类加载器:
java.lang.ClassLoader的子类,用户可以定制类的加载方式。
JVM自带的加载器
Java虚拟机自带了以下几种加载器。
1.根(Bootstrap)类加载器:
该加载器没有父加载器。
它负责加载虚拟机的核心类库,如java.lang.*等。
根类加载器从系统属性sun.boot.class.path所指定的目录中加载类库。
根类加载器的实现依赖于底层操作系统,属于虚拟机的实现的一部分,它并没有继承java.lang.ClassLoader类,它是用C++写的。
2.扩展(Extension)类加载器:
它的父加载器为根类加载器。
它从java.ext.dirs系统属性所指定的目录中加载类库,或者从JDK的安装目录的jre\lib\ext子目录(扩展目录)下加载类库,如果把用户创建的JAR文件放在这个目录下,也会自动由扩展类加载器加载。
扩展类加载器是纯Java类,是java.lang.ClassLoader类的子类。
3.系统(System)类加载器:
也称为应用类加载器,它的父加载器为扩展类加载器。
它从环境变量classpath或者系统属性java.class.path所指定的目录中加载类,它是用户自定义的类加载器的默认父加载器。
系统类加载器是纯Java类,是java.lang.ClassLoader类的子类。
注意:这里的父加载器概念并不是指类的继承关系,子加载器不一定继承了父加载器(其实是组合的关系)。
用户自定义类加载器
除了以上虚拟机自带的类加载器以外,用户还可以定制自己的类加载器(User-defined Class Loader)。
Java提供了抽象类java.lang.ClassLoader,所有用户自定义的类加载器都应该继承ClassLoader类。
类加载的父委托机制
从JDK 1.2版本开始,类的加载过程采用父亲委托机制,这种机制能更好地保证Java平台的安全。
在父委托机制中,除了Java虚拟机自带的根类加载器以外,其余的类加载器都有且只有一个父加载器,各个加载器按照父子关系形成了树形结构。
当Java程序请求加载器loader1加载Sample类时,loader1首先委托自己的父加载器去加载Sample类,若父加载器能加载,则由父加载器完成加载任务,否则才由loader1本身加载Sample类。
说明具体过程的一个例子:
loader2首先从自己的命名空间中查找Sample类是否已经被加载,如果已经加载,就直接返回代表Sample类的Class对象的引用。
如果Sample类还没有被加载,loader2首先请求loader1代为加载,loader1再请求系统类加载器代为加载,系统类加载器再请求扩展类加载器代为加载,扩展类加载器再请求根类加载器代为加载。
若根类加载器和扩展类加载器都不能加载,则系统类加载器尝试加载,若能加载成功,则将Sample类所对应的Class对象的引用返回给loader1,loader1再返回给loader2,从而成功将Sample类加载进虚拟机。
若系统加载器不能加载Sample类,则loader1尝试加载Sample类,若loader1也不能成功加载,则loader2尝试加载。
若所有的父加载器及loader2本身都不能加载,则抛出ClassNotFoundException异常。
总结下来就是:
每个加载器都优先尝试用父类加载,若父类不能加载则自己尝试加载;若成功则返回Class对象给子类,若失败则告诉子类让子类自己加载。所有都失败则抛出异常。
定义类加载器和初始类加载器
若有一个类加载器能成功加载Sample类,那么这个类加载器被称为定义类加载器。
所有能成功返回Class对象的引用的类加载器(包括定义类加载器,即包括定义类加载器和它下面的所有子加载器)都被称为初始类加载器。
假设loader1实际加载了Sample类,则loader1为Sample类的定义类加载器,loader2和loader1为Sample类的初始类加载器。
父子关系
需要指出的是,加载器之间的父子关系实际上指的是加载器对象之间的包装关系,而不是类之间的继承关系。
一对父子加载器可能是同一个加载器类的两个实例,也可能不是。
在子加载器对象中包装了一个父加载器对象。
例如loader1和loader2都是MyClassLoader类的实例,并且loader2包装了loader1,loader1是loader2的父加载器。
当生成一个自定义的类加载器实例时,如果没有指定它的父加载器(ClassLoader构造方法无参数),那么系统类加载器就将成为该类加载器的父加载器。
父委托机制优点
父亲委托机制的优点是能够提高软件系统的安全性。
因为在此机制下,用户自定义的类加载器不可能加载应该由父加载器加载的可靠类,从而防止不可靠甚至恶意的代码代替由父加载器加载的可靠代码。
例如,java.lang.Object类总是由根类加载器加载,其他任何用户自定义的类加载器都不可能加载含有恶意代码的java.lang.Object类。
命名空间
每个类加载器都有自己的命名空间,命名空间由该加载器及所有父加载器所加载的类组成。
在同一个命名空间中,不会出现类的完整名字(包括类的包名)相同的两个类。
在不同的命名空间中,有可能会出现类的完整名字(包括类的包名)相同的两个类。
运行时包
由同一类加载器加载的属于相同包的类组成了运行时包。
决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看定义类加载器是否相同。
只有属于同一运行时包的类才能互相访问包可见(即默认访问级别)的类和类成员。
这样的限制能避免用户自定义的类冒充核心类库的类,去访问核心类库的包可见成员。
假设用户自己定义了一个类java.lang.Spy,并由用户自定义的类加载器加载,由于java.lang.Spy和核心类库java.lang.*由不同的类加载器加载,它们属于不同的运行时包,所以java.lang.Spy不能访问核心类库java.lang包中的包可见成员。
参考资料
圣思园张龙老师Java SE系列视频教程。
转载于:https://www.cnblogs.com/mengdd/p/3562540.html
Java虚拟机JVM学习05 类加载器的父委托机制相关推荐
- Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论
Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...
- 类加载器 java委托机制_解析Java虚拟机中类的初始化及加载器的父委托机制
类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始化: 2.在静态代码块中进行初始化. 没有 ...
- axure 富文本编辑器_Java的类加载器与双亲委托机制
目录: 类加载器 java.lang.ClassLoader类 URLClassLoader与SecureClassLoader ClassLoader常见方法源码分析 双亲委托机制 图解 源码角度分 ...
- java 父委托机制优点_类加载器及父亲委托机制
一.类加载器 1.在Java中,有两种类型的类加载器,分别是JVM自带的类加载器和用户自定义的类加载器. 2.JVM自带的类加载器有三种,如下: 根(Bootstrap)类加载器:该加载器没有父加载器 ...
- 《深入理解JAVA虚拟机》学习日志----一、自动内存管理机制(2.垃圾收集器与内存分配策略)
二.垃圾收集器与内存分配策略 前言:讨论的区域集中在Java堆和方法区中,而其他几个区域的内存分配和回收都具备确定性,所以不需过多考虑回收 的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了. ...
- java虚拟机预先加载哪些类_Java虚拟机JVM学习02 类的加载概述
Java虚拟机JVM学习02 类的加载概述 类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对 ...
- JVM——深入理解类加载器
类加载器相关内容有很多,大概分以下几个关键点进行学习, 参考链接 https://www.bilibili.com/video/av47756459 目录 概览 JVM与程序的生命周期 类加载器生命周 ...
- Java高新技术第一篇:类加载器详解
首先来了解一下字节码和class文件的区别: 我们知道,新建一个java对象的时候,JVM要将这个对象对应的字节码加载到内存中,这个字节码的原始信息存放在classpath(就是我们新建Java工程的 ...
- 深入理解Java虚拟机——JVM类加载机制(类加载过程和类加载器)
一.什么是类加载机制? 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 二.类加载的时机 类 ...
最新文章
- 关于:last-child的一点见解
- SP-1. 五月学习计划(study plan)
- centos7 glpi 安装 Fusioninventory-agent 自测部署安装
- ros自己写避障算法_迷雾学术篇|视觉感知的无人机动态避障(下篇)
- Java的ClassLoader
- Oracle用rowid删除同一张表的重复记录
- 【Flink】Flink各种UDF简介
- java实现mqtt服务端_基于Swoole使用MQTT协议连接阿里云物联网平台设备实现消息订阅
- VMware vSphere 服务器虚拟化之二十七桌面虚拟化之View中使用Thinapp软件虚拟化
- block 在ARC和非ARC下的不同含义
- Atiti attilax主要成果与解决方案与案例rsm版 v2
- python网络编程 赵宏_【干货收藏】Python面试指南大全
- 基于CC2430的基础实验5---时钟模式
- for(int i = 0;i 10;i++)和int i;for(i = 0;i 10;i++)
- 经典算法:鸡蛋掉落问题
- intel英特尔架构
- 非微信官方网页解决方法
- 【转】C++ std::tr1::shared_ptr使用
- Win10 wsl-安装教程
- Java中的项目结构简述(项目、模块、包、类)
热门文章
- python爬虫正则表达式实例-3.Python爬虫入门_正则表达式(简单例子)
- python手机版安卓-手机随时随地写Python,还可以开发安卓APP,太厉害了!
- java和python的比较-java学习笔记(与python对比来学)
- python绘制三维散点图-Python散点图与三维图
- python应该怎么自学-Python 应该怎么学?
- python画折线图详解-利用python画折线图
- 怎么自学python 知乎-你是如何自学 Python 的?
- python代码需要背吗-Python代码需要缩进吗
- python语音在线编辑-python实现语音在线合成,让你的小说自己念给你听
- python 文字语音朗读-python 利用pyttsx3文字转语音过程详解