Java中的ClassLoader

  Java中类的加载过程(如Dog类):

 

  1. 通过类型信息定位Dog.class文件。
  2. 载入Dog.class文件,创建相应的Class对象。
  3. 执行父类的静态字段定义时初始化语句和父类的静态初始化块。
  4. 执行子类的静态字段定义时初始化语句和子类的静态初始化块。
  5. 当使用new Dog()方式时,在堆上为Dog对象分配存储空间,并清零分配的存储空间。
  6. 执行父类的字段定义时初始化语句和父类的构造函数。
  7. 执行子类的字段定义时初始化语句和子类的构造函数。

(参考Java编程思想,部分是自己测试的结果,还没有看到相关资料,这个顺序和C#的顺序好像有比较大的差别)

 

我们知道每个Java类编译后会生成一个.class文件,里面除了存储了类的字节码之外,还存储了和该类对应的Class对象的信息(包含一些用于反射的信息)。在JVM中,通过类加载器(ClassLoader)来实现Class对象的创建。

 

在Object类中有public的getClass()方法,我们可以通过该方法获取与之对应的Class对象。在获取类对应的Class对象后,我们就可以通过newInstance()方法或者通过获取其Constructor的方法来创建该类的实例,也可以通过Class对象获取类或实例相关的更多信息,如方法,字段等,即反射的功能。另外我们也可以通过Class.forName()方法,通过传入类字符串的方式来创建类的实例。(通过Class对象创建类实例和通过forName方法创建类实例是否有联系呢?这两种创建类的实例和直接通过new创建类实例是否也有联系呢?)

 

然而Dog.class文件是如何定位的?Dog.class文件是如何被加载并解析的?Class对象又是如何生成的呢?这就是ClassLoader需要解决的问题,也是这篇文章中接下来要讲述的。

 

ClassLoader的工作原理

 

在Java内部实现了三种类型的ClassLoader:Bootstrap ClassLoader,Extension ClassLoader, System ClassLoader。这三个ClassLoader通过parent形成一条单向链,其中Bootstrap处于链尾,而System ClassLoader处于链头。

 

Bootstrap ClassLoader

Bootstrap ClassLoader用于在启动JVM时加载类,以使JVM能正常工作,因而它是用Native代码实现的,最早被创建出来,处于最底层。

Bootstrap ClassLoader将搜索Java核心库(%JAVA_HOME%\jre\lib),如rt.jar、i18n.jar等,在这些核心库中包含了Java的核心类,即Bootstrap ClassLoader用于加载Java的核心类,包括java.lang、java.io等包中的类。

 

Extension ClassLoader

Extension ClassLoader位于链的中间层,它将搜索特定的标准扩展目录。该标准扩展目录在不同的JVM实现中不一定相同,在sun的JVM中,它是%JRE_HOME% \lib\ext,具体路径可以通过java.ext.dirs系统属性值获取。该标准扩展目录存在的目的在于扩展和共享,应用程序厂商可以将部分共享库放置于此,而不是各自程序的目录下的多份拷贝。在开发过程中,我们也可以把部分常用的库放置于此,而不必每次都去配置环境。

 

System ClassLoader

System ClassLoader位于链的最顶层,它将搜索CLASSPATH中配置的目录和jar文件。

 

三种ClassLoader的协同工作

既然系统中有三种不同的ClassLoader,那么一个类的加载是用那个ClassLoader呢?在Java中,是通过“代理模型(delegation model)”来决定使用哪个ClassLoader来加载类的(读取.class文件,并创建相应的Class对象)。当一个类需要被加载的时候,系统默认通过System ClassLoader来加载该类;然而System ClassLoader并不立即加载该类,它会将加载的行为代理给其parent去加载,只有当其parent不能加载该类的时,System ClassLoader才去搜索CLASSPATH中的目录和jar文件以加载该类,若找到对应的.class文件,则加载该类,否则抛出ClassNotFoundException。当它将加载的行为代理给Extension ClassLoader并最终代理给Bootstrap ClassLoader的时候,他们也做的是相似的事情。从设计的角度,这其实就是一种职责链模式(Chain of Responsibility Pattern

 

那么Java为什么需要这种代理模型呢?答案是出于安全的考虑。Java是一种安全的编程语言,它会对每个加载的类执行安全检查,但是对Java核心库中的类是不执行安全检查的(即他们是受JVM信赖的)。(什么是安全检查?以我现在所知,就是用户可以通过security manager来控制特定目录的访问权限,如何使用这些控制将会是另一个主题。对安全检查是否还有其他的呢?)那么假如用户可以加载自己编写的和核心库同名的类(如java.lang.Object),那么这些用户编写的类就可以绕过安全检查,从而为一些恶意用户提供了一种破坏的途径。然而在使用这种代理模型后,类的加载首先会代理到Bootstrap ClassLoader中实行加载,如果它发现当前核心类库中可以加载对应的类,系统会加载核心库中的类,而不会加载用户编写的类。

 

但是如果只是这样,还不足以保证类的加载的安全。因为用户完全可以定义自己的ClassLoader,在自己的ClassLoader中破坏这种代理模型,那么用户自己写的java.lang.Object就可以被加载了。为了解决这个问题,在Java中认为两个类名相同的实例,如果加载他们的ClassLoader不同,那么他们是不同的类型,即他们之间不能转换,而且用instanceof操作符返回的是false。这样的话,即使用户加载了自己的java.lang.Object类,它也不是系统认为可以信赖的java.lang.Object,那么它就绕不过安全检查机制。(以上的描述只是我的猜想,我还没有看到相关的资料提到该问题,因而有待验证。)

 

有人说使用这种机制可以实现兼容性的升级,在软件的旧版本中使用某个旧版本的类,在升级的某些新部分中可以使用相同类的新版本,即实现内存中保留一个类的两个版本。我认为这种不应该是一种推荐的做法,在内存中保留一个类的两个版本极易在运行是引起一些莫名其妙的错误。

 

很可惜,我没能找到以上三种ClassLoader的源码,看不了内部的实现。在Java中,它们都是通过ClassLoader这个抽象类来表示的。以下简单的介绍一下ClassLoader内部的成员

(其中Extension ClassLoader的实现类为:sun .misc.Launcher$ExtClassLoader)

 

来自 http://dlevin.iteye.com/blog/772604

转载于:https://www.cnblogs.com/hellocyc/p/4409722.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

excel删除无尽空白行_excel如何批量删除空白行 巧用 ctrl+G 只需1秒 最常用的技巧...

工作中我们使用excel通常都会遇到这种情况,就是表格中有很多多余的空行。我们需要把多余的空行删除。 如果空行只有一两行的话,可以把鼠标放在空白行上,然后点击鼠标右键,在弹出的菜单中选择删除菜单。 在弹出的删除确定窗口中&am…

DevOps的前世今生

2019独角兽企业重金招聘Python工程师标准>>> 目前在国外,互联网巨头如Google、Facebook、Amazon、LinkedIn、Netflix、Airbnb,传统软件公司如Adobe、IBM、Microsoft、SAP等,亦或是网络业务非核心企业如苹果、沃尔玛、索尼影视娱乐…

【转】最牛B的编码套路

最近,我大量阅读了Steve Yegge的文章。其中有一篇叫“Practicing Programming”(练习编程),写成于2005年,读后令我惊讶不已: 与你所相信的恰恰相反,单纯地每天埋头于工作并不能算是真正意义上的…

ecshop 广告设置

最近公司准备做个商城,让我从JAVA转过去,好吧,先看下吧,反正也得做。接到手里的是一套已经成型的模板,但是二次开发必须得了解下机制、文件、响应、设置什么的,也是个新手,写点东西给后面更新的…

linux 信号_Linux信号机制

信号就是一条消息,通知进程系统中发生了什么事,每种信号都对应着某种系统事件。一般的底层硬件异常是由内核的异常处理程序处理的,它对用户进程来说是透明的。而信号机制,提供了一种方法通知用户进程发生了这些异常。例如&#xf…

DOxygen for C++使用说明——添加数学公式

公式 Doxygen允许你把 公式显示在最终的输出中(这个功能仅限于HTML和输出).为了可以在HTML documentation显示公式(转化为图片),你必须安装以下软件: latex: 编译器, 被用来解析公式, 首先提取公式写到一…

Tomcat 的 DefaultServlet

问题描述: 群里有人测试 Spring MVC,没有配置任何Controller,只配置了一个view resolver,指定了前缀后缀。 然后,他问的是 当访问 localhost:8080/test 的时候,为什么会被重定向到 localhost:8080/test/ &a…

spss练习数据_SPSS篇——如何在成千上百万个数据中标识重复个案

本文就带大家来学习一个小技巧,如何运用SPSS标识重复个案。我们都知道在Excel中,通常会用到“筛选”功能来选出指定条件相同的单元格。那么在SPSS中,如何在成千上百万个数据中筛选出重复的个案呢? 小编就是要告诉你,几…

DOxygen for C++使用说明——Markdown支持

自Doxygen 版本1.8.0,Markdown被引进。 接下来,我们将先简单介绍标准的Markdown语法,读者可以进入Markdown官网查询更详细的细节。然后讨论一下Doxygen支持的Markdown扩展,最后讨论一下Doxygen对Markdown标准的实现细节。 Stand…

方程式漏洞之复现window2008/win7 远程命令执行漏洞

前几天就想写的,因为一些缘故就没写。此次是在外网环境下进行的。大家在内网中也一个样。 方法: 使用Eternalblue模块,剑测是否有漏洞然后msf生成一个dll直接反弹shell. PS:win版本的不知道缘何生成出来的dll是0kb 我就在自己本地…

客服会话 小程序 如何发起_小程序、公众号、App三者如何融合布局?这里有一份避坑指南...

对产品经理来说,小程序无疑是2020年最火爆的词之一了。我们能看到,就在今年疫情期间,小程序DAU达到4.5亿,而超市、生鲜果蔬、社区购物等都同比增长100个点左右,小程序的商业价值很明显地在快速释放。小程序如此火爆&am…

DOxygen for C++使用说明——注释代码二

这一次我在谷歌搜索中检索到了Doxygen在github的仓库,进去一看,令人大喜,github仓库里含有了一个Doxygen的官方配置文件Doxyfile,于是下载下来,发现Doxyfile已经配置了将仓库中的\src文件编译成Documentation,并且将结果放在了dox…

python super()(转载)

一、问题的发现与提出 在Python类的方法(method)中,要调用父类的某个方法,在Python 2.2以前,通常的写法如代码段1: 代码段1: class A:def __init__(self):print "enter A"print "…

Swagger+Spring mvc生成Restful接口文档

2019独角兽企业重金招聘Python工程师标准>>> Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端…

JavaScript——变量与基本数据类型

前言 JavaScript中的变量为松散类型,所谓松散类型就是指当一个变量被申明出来就可以保存任意类型的值,就是不像SQL一样申明某个键值为int就只能保存整型数值,申明varchar只能保存字符串。一个变量所保存值的类型也可以改变,这在Ja…

vscode可以打开jupyternotebook吗_刚刚,官方宣布 VS Code 支持 Python 全开发了!

关注Python高校每天早上23:10准时推送北京时间 2019 年 9 月 21 日,PyCon China 2019 在上海举行。在下午的演讲中,来自微软开发工具事业部的资深研发工程师韩骏做了主题为《Python 与 Visual Studio Code 在人工智能应用中的最佳 Azure 实践》的演讲。在…

springboot默认数据源如何设置连接数_Spring Boot系列之配置数据库连接池

在实际的应用开发中,与数据库交互通常使用数据库连接池来重用Connection对象,减少资源消耗。Spring Boot 的数据源是自动配置的。在 Spring Boot 2.2.1 版本中,有几种数据源配置可选,它们按照 HikariCP -> Tomcat -> DBCP2 …

Beyond Compare 3.3.8 build 16340 + Key

本文摘录自冰点社区:http://forum.z27315.com/topic/14746-beyond-compare-338-build-16340-key/ Download Beyond Compare 3 Current Version: 3.3.8, build 16340, released June 19, 2013 Windows 版本 Windows Standard and Pro EditionsEnglish version 5800k…

hdu 1198 Farm Irrigation

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid1198 题目大意: 有一大块土地需要浇水,这块土地由很多的小块土地(有十一种)组成,小块土地上有水沟,问至少需要建几个井,才能灌…

小米一键上锁工具_小米首款高端全自动智能锁火热预售中,一触开启全自动时代...

近些年,随着科技的发展,人工智能逐渐走入大众视野。人类社会也正从信息时代向“智能时代”过渡,在整个过程中智能家居领域的蓬勃发展可谓当仁不让,一直备受用户瞩目。智能锁作为家的第一道守护防线,家庭物联网入口的关…