Android(java)学习笔记106-1:深入分析Java ClassLoader原理
1. 前言:
2. Java ClassLoader的组成
Bootstrap ClassLoader 根类加载器:
主要负责加载java中的核心类库。是用C++代码实现的,在java虚拟机启动后初始化
Extension ClassLoader 扩展类加载器:
负责JRE的扩展目录中jar包的加载。在JDK中JRE的lib目录下ext目录中
System ClassLoader 系统类的加载器(也叫:App ClassLoader):
负责在JVM启动的时候加载来自Java命令的class文件,以及classpath环境变量所指定的jar包和类路径。
注意:我们自己编写的java文件转化为class字节码文件之
后,是App ClassLoader加载的.
3. Java ClassLoader的体系结构:
4. ClassLoader类加载器加载类(Class)的步骤:
(1)检测),否则接着执行()
(2)如果)执行;如果)
(3)请求),否则接着执行()
(4)请求),否则跳到()
(5)),如果)
(6)从文件中载入Class,)
(7)抛出ClassNotFoundException异常
(8)返回对应的java.lang.Class对象
其中,()()允许重写ClassLoader的findClass()方法来实现自己的载入策略,甚至重写loadClass()来实现自己的载入过程。
5. ClassLoader加载类的原理:
(1)原理介绍:
ClassLoader使用的是双亲委托模型来搜索加载类的,每个ClassLoader实例都有一个父类加载器的引用(不是继承的关系,是一个包含的关系),虚拟机内置的类加载器(Bootstrap ClassLoader)本身没有父类加载器,但可以用作其它ClassLoader实例的的父类加载器。
当一个ClassLoader实例需要加载某个类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器Bootstrap ClassLoader试图加载,如果没加载到,则把任务转交给Extension ClassLoader试图加载,如果也没加载到,则转交给App ClassLoader 进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等URL中加载该类。如果它们都没有加载到这个类时,则抛出ClassNotFoundException异常。
否则将这个找到的类生成一个类的定义,并将它加载到内存当中,最后返回这个类在内存中的Class实例对象。
(2)为什么要使用双亲委托这种模型 ?
第1个原因:可以避免重复加载,当父类已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
第2个原因:考虑安全因素,一些非系统的class是不可靠的,若定义一个恶意的java.io.File类覆盖JDK自带的类会带来不安全性。而使用双亲委托机制的话该File类永远不会被调用,因为委托BootStrapClassLoader加载后会加载JDK中的File类而不会加载自定义的这个。
(3)JVM在搜索类的时候,又是如何判定两个class是相同的呢?
JVM在判定两个class是否相同时,不仅要判断两个类名是否相同,而且要判断是否由同一个类加载器实例加载的。
只有两者同时满足的情况下,JVM才认为这两个class是相同的。
就算两个class是同一份class字节码,如果被两个不同的ClassLoader实例所加载,JVM也会认为它们是两个不同class。比如网络上的一个Java类org.classloader.simple.NetClassLoaderSimple,javac编译之后生成字节码文件NetClassLoaderSimple.class,ClassLoaderA和ClassLoaderB这两个类加载器并读取了NetClassLoaderSimple.class文件,并分别定义出了java.lang.Class实例来表示这个类,对于JVM来说,它们是两个不同的实例对象,但它们确实是同一份字节码文件,如果试图将这个Class实例生成具体的对象进行转换时,就会抛运行时异常java.lang.ClassCaseException,提示这是两个不同的类型。
Android(java)学习笔记106-1:深入分析Java ClassLoader原理的更多相关文章
- java学习笔记(1)java的基础介绍 、JDK下载、配置环境变量、运行java程序
java工程师是开发软件的 什么是软件呢? 计算机包括两部分: 硬件: 鼠标.键盘.显示器.主机箱内部的cpu.内存条.硬盘等 软件: 软件包括:系统软件和应用软件 系统软件:直接和硬件交互的软件:w ...
- Android(java)学习笔记45:深入分析Java ClassLoader原理
1. 前言: Android中的动态加载机制能更好的优化我们的应用,同时实现动态的更新,这就便于我们管理我们的应用,通过插件化来减轻我们的内存以及CPU消耗,在不发布新版本的情况下能更新某些模块. 当 ...
- Java学习笔记(二)——Java操作properties文件
[前面的话] 前段时间在学习和玩java web相关的东西,对于这些技术,一边学习,一边做东西,一边总结,希望可以一边成长和有所收获.有时总是思考太多反而成为了前进的阻力,所以对于生活还是简单一些,不 ...
- Java学习笔记(一) java介绍
编程语言分为:编译型语言和解释型语言. 编译型语言需要经过特定编译器通过一次性编译,成为该特定平台硬件可执行的机器码,可脱离开发环境独立运行,运行效率较高,但是无法跨平台移植. 解释型语言需要经过特定 ...
- Java学习笔记二十八:Java中的接口
Java中的接口 一:Java的接口: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承 ...
- Java学习笔记(八)——java多线程
[前面的话] 实际项目在用spring框架结合dubbo框架做一个系统,虽然也负责了一块内容,但是自己的能力还是不足,所以还需要好好学习一下基础知识,然后做一些笔记.希望做完了这个项目可以写一些dub ...
- Java学习笔记(十七)——java序列化
[前面的话] 做项目总是要用到很多东西,遇到一个新的知识,并不是这个知识出来的时间短,而是对于自己来说是新的,所以就需要自己去学习,希望今后可以提高学习的效率. 这篇文章是关于Java 序列化的,选择 ...
- 【Java学习笔记之十七】Java中普通代码块,构造代码块,静态代码块区别及代码示例分析
//执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. 1 普通代码块 //普通代码块:在 ...
- 【Java学习笔记之十】Java中循环语句foreach使用总结及foreach写法失效的问题
foreach语句使用总结 增强for(part1:part2){part3}; part2中是一个数组对象,或者是带有泛性的集合. part1定义了一个局部变量,这个局部变量的类型与part2中的对 ...
随机推荐
- 初识MFC,WinForm,WPF,Q't
MFC和QT是C++中常见的GUI框架,而WinForm和WPF是C#中常用的框架,不过我们一般很少叫WinForm框架,可能直接叫图形控件类库更多点.反正只是个称呼罢了,爱咋叫就咋叫.另外WinFo ...
- HDU-4726 Kia's Calculation 贪心
题目链接:http://acm.hdu.edu.cn/userstatus.php?user=zhsl 题意:给两个大数,他们之间的加法法则每位相加不进位.现在可以对两个大数的每位重新排序,但是首位不 ...
- 那些经常被遗忘的 Java 面试题
静态类和静态方法 如果一个类要被声明为static的,只有一种情况,就是静态内部类. 静态内部类实际上与普通类(即类名必须与文件名一样的顶级类)一样,只是静态内部类在某一类的内部定义了而已,既然是类, ...
- Java缓存学习之一:缓存
一.缓存 1.什么是缓存? 缓存是硬件,是CPU中的组件,CPU存取数据的速度非常的快,一秒钟能够存取.处理十亿条指令和数据(术语:CPU主频1G),而内存就慢很多,快的内存能够达到几十兆就不错了,可 ...
- POJ Wormholes (SPFA)
http://poj.org/problem?id=3259 Description While exploring his many farms, Farmer John has discovere ...
- ASP导出Word带页眉页脚,中文不乱码
关键代码: <% Response.Clear() Response.CodePage= Response.Charset="UTF-8" Response.ContentT ...
- Thinkphp框架----微信公众测试号开发
最开始的一个步骤.注册一个微信公众测试号.URL:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login; 接口配置的信息,对新手 ...
- MEF 编程指南(九):部件生命周期
理解 MEF 容器部件生命周期和实现是非常重要的事情.考虑到 MEF 关注可扩展应用程序.这变得尤为重要.生命期可以解释为期望部件的共享性(transitively, its exports) 共 ...
- main方法执行之前,做什么事
1.我们知道程序的入口是main方法,那么在执行main方法之前,需要做些什么准备工作呢? 2.main方法执行之前,必须要把non-local static对象构造完成.static对象有:全局对象 ...
- Codeforces Round #185 (Div. 2) A. Whose sentence is it? 水题
A. Whose sentence is it? Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/ ...