深入了解java虚拟机(JVM) 第十二章 类加载器
一、什么是类加载器
类加载器是一个用来加载类文件的类,Java源代码通过javac编译器编译成类文件,然后JVM来执行类文件中的字节码来执行程序。需要注意的是,只有被同一个类加载器加载的类才可能会相等。相同字节码被不同的类加载器加载的类不相等。
二、类加载器分类
1.启动类加载器
由C++实现,是虚拟机的一部分,用于加载javahome下的lib目录下的类;
2.扩展类加载器
加载javahome下/lib/ext目录中的类;
3.应用程序类加载器
加载用户类路径上的所指定的类库,也就是我们所用的类加载器;
三、自定义加载器
在jvm中,除了以上三种类加载器外,我们还可以自定义加载器,自定义加载器的方法有三步
1.定义一个类继承classloader
2.重写loadClass方法
3.实例化class对象
我们看下面的例子:
package com.example.demo; import java.io.InputStream; public class Test1 extends ClassLoader{ @Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
//name的值为com.example.demo.Test1,他是类的绝对路径
//截取name后 fileName的值为Test1.class
//加上.class表示这是个class文件
String fileName=name.substring(name.lastIndexOf(".")+1)+".class";
//加载这个class文件
InputStream input=getClass().getResourceAsStream(fileName); //判断input是否为空
//为空就证明当前文件夹下没有这个文件
//如果为空就让父类加载器去加载它
if (input==null) {
return super.loadClass(name);
}
//如果不为空,就用当前的类加载器进行加载
try {
//简单的IO流操作,用创建一个byte数组,然后将输入流输入数组
byte [] buff=new byte[input.available()];
input.read(buff);
//方便测试,我们加上一行代码
System.out.println("自定义类加载器启动");
//当读取后,我们需要实例化class对象
//在这里我们使用java为我们提供的defineClass方法实例化对象
//defineClass的参数意思:要加载类的绝对路径,读取的数组,从第几位开始读,读到第几位结束
return defineClass(name, buff, 0, buff.length);
} catch (Exception e) {
throw new ClassNotFoundException();
}
} }
上面我们已经完成了一个自定义类加载器,接下来使用一个方法来测试
package com.example.demo; public class TestMain { public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Test1 test1=new Test1();
//使用反射,用自定义类加载器加载并创建一个实例会对象
Object obj1=test1.loadClass("com.example.demo.TestMain").newInstance();
//使用反射,用系统默认的类加载器加载并创建一个实例会对象
Class<?> cls = Class.forName("com.example.demo.TestMain");
Object obj2=cls.newInstance();
System.out.println(obj1.getClass());
//判断obj1是否是TestMain类的实例
boolean b1=obj1 instanceof TestMain;
System.out.println("obj1是不是TestMain的实例:"+b1);
//判断obj2是否是TestMain类的实例
boolean b2=obj2 instanceof TestMain;
System.out.println("obj2是不是TestMain的实例:"+b2);
}
}
测试的结果为:
为什么obj1不是TestMain的实例?这就是回来我们一开始说道的,相同的字节码被不同的类加载器加载的类不相等。
四、自定义加载器的优势
1.高度的灵活性;
2.通过自定义类加载器可以实现热部署
3.代码加密
五、类加载器之间的协同工作--双亲委派模型
在jvm中有的各种类加载器,他们之间是通过双亲委派模型的类加载机制进行协同工作,如图:
双亲委派模型的工作原理主要是:
1)如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器完成。
2)每一层的类加载器都把类加载请求委派给父类加载器,直到所有的类加载请求都应该传递给顶层的启动类加载器。
3)如果顶层的启动类加载器无法完成加载请求,子类加载器尝试去加载,如果连最初发起类加载请求的类加载器也无法完成加载请求时,将会抛出classNotFoundException,而不再调用其子类加载器去进行类加载。
双亲委派模式的类加载机制的优点:
java类它的类加载器一起具备了一种带优先级的层次关系,越是基础的类,越是被上层的类加载器进行加载,保证了java程序的稳定运行。
深入了解java虚拟机(JVM) 第十二章 类加载器的更多相关文章
- 第十二章 类加载器&反射
12.1.类加载器 12.1.1.类加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载.类的连接.类的初始化这三个步骤来对类进行初始化.如果不出现意外情况,JVM将会连续完成 ...
- “全栈2019”Java多线程第三十二章:显式锁Lock等待唤醒机制详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- Java虚拟机学习(5):类加载器(ClassLoader
类加载器 类加载器(ClassLoader)用来加载 class字节码到 Java 虚拟机中.一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源文件在经过 Javac之后就被转换成 ...
- 《深入理解Java虚拟机》之(二、垃圾收集器与内存分配策略)
程序计数器.虚拟机栈.本地方法栈3个区域随线程而生,随线程而灭,这几个区域的内存分配和回收都具备确定性,不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟着回收了,而java堆和方法区 ...
- 深入理解Java虚拟机学习笔记(二)-----垃圾收集器与内存分配策略
写在前面 本节常见面试题: 如何判断对象是否死亡(两种方法). 简单的介绍一下强引用.软引用.弱引用.虚引用(虚引用与软引用和弱引用的区别.使用软引用能带来的好处). 如何判断一个常量是废弃常量 如何 ...
- JVM体系结构之二:类加载器
一.概述 定义:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型.类加载和连接的过程都是在运行期间完成的. 二. 类的加载 ...
- (转)《深入理解java虚拟机》学习笔记8——Tomcat类加载器体系结构
Tomcat 等主流Web服务器为了实现下面的基本功能,都实现了不止一个自定义的类加载器: (1).部署在同一个服务器上的两个web应用程序所使用的java类库可以相互隔离. (2).部署在同一个服务 ...
- java 面向对象编程 --第十二章 JDK常用类
1. 系统类 java.lang包 System类 sys.out;sys.exit;sys.gc; sys.currentTimeMillis();----得到从1970-01-01到当前时间 ...
- 读书笔记,《深入理解java虚拟机》,第三章 垃圾收集器与内存分配策略
要实现虚拟机,其实人们主要考虑完成三件事情: 第一,哪些内存需要回收: 第二,什么时候回收: 第三,如何回收. 第二节,对象已死吗 垃圾收集其实主要是针对java堆里面的数据来说的,传统的垃圾收 ...
随机推荐
- lua的注释
和C语言一样,lua也有单行注释和多行注释之分 单行注释: 采用“--”来对注释后面的字符进行注释,类似于 ISO C90之后的 C语言的注释"//" 多行注释:采用"- ...
- 迷你MVVM框架 avalonjs 学习教程8、属性操作
属性操作是DOM操作很大的一块,它包括类名操作,表单元素的value属性操作,元素固有属性的管理,元素自定义属性的管理,某些元素的一些布尔属性的操作.大多数情况下,元素属性的值是字符串类型,我们称之为 ...
- Trait 概览
Trait是PHP 5.4引入的新概念,看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么:提供模块化实现.Trait ...
- DataStage 六、安装和部署集群环境
DataStage序列文章 DataStage 一.安装 DataStage 二.InfoSphere Information Server进程的启动和停止 DataStage 三.配置ODBC Da ...
- mysql查询今天、昨天、近7天、近30天、本月、上一月的SQL语句
mysql查询今天.昨天.近7天.近30天.本月.上一月的SQL语句 这篇文章主要介绍了mysql查询今天.昨天.近7天.近30天.本月.上一月的SQL语句,一般在一些统计报表中比较常用这个时间段,需 ...
- centos环境下登录mysql报 ERROR 1045 (28000)怎么解决
centos环境下登录mysql报 ERROR 1045 (28000)怎么解决 新入手一台虚拟机,Centos7系列的操作系统,安装mysql后,执行连接出现了Mysql ERROR 1045 (2 ...
- scalr调用openstack接口
- 使用Nmap攻击靶机和使用Wireshark进行嗅探、分析
使用Nmap攻击靶机和使用Wireshark进行嗅探.分析 在上一次课中已经对Nmap的使用.原理已经做了很多学习,这次的课更多地针对Wireshark进行学习和使用. 使用192.168.200.1 ...
- Npoi List DataTable导出一个Excel多个sheet 下载
参考: http://blog.csdn.net/zhouqinghe24/article/details/8649346 参考下载http://www.cnblogs.com/dyllove98/a ...
- Codeforces788A Functions again 2017-04-12 18:22 56人阅读 评论(0) 收藏
C. Functions again time limit per test 1 second memory limit per test 256 megabytes input standard i ...