java虚拟机杂谈二 java类加载器

java类加载器作用:从磁盘、网络或其他来源加载class文件(字节码文件)加载到jvm内存中,并对字节码进行校验,解析和初始化,生成对应的Class对象。

 

class文件(字节码文件)的来源有多种

  • jdk编译的class文件,先是用编辑工具(如eclipse)编写java代码;
  • Jar文件,原始jar包,包含了很多class文件;
  • 网络,可以从网络中加载class文件;
  • jsp,jsp编译后也是生成class文件;
  • 数据库中,保存在数据库中,可加密,安全性高;
  • 运行时计算生成,java动态代理技术;

 

JVM中类加载器的树状层次结构

  1. 启动类加载器(Bootstrap ClassLoader):C++实现,用来加载jre核心库;
  2. 扩展类加载器(Extendsion ClassLoader):用来加载java扩展类库,/lib/ext目录下;
  3. 应用程序类加载器(Application ClassLoader):加载用户类路径上的类,classpath;
  4. 自定义类加载器(custom class loader):开发人员可以通过继承 java.lang.ClassLoader类的方式实现自己的类加载器,以满足一些特殊的需求;
网引图

java类加载器加载类的过程分为加载,链接,初始化三步,其中链接包括验证,准备,解析等一些验证操作;

网引图

加载:通过一个类的全限定名来获取此类的二进制流,将二进制流数据转化为jvm内存运行时数据结构,做好外部引用准备;

链接:验证目的是防止字节流数据信息危害虚拟机自身安全;准备变量的初始值等,类和接口等的解析;

初始化:执行init方法;

java类加载器默认加采用的是双亲委派机制

什么是双亲委派机制?

当一个类加载器接收到一个类加载的任务时,不会立即开始加载,而是将加载任务委托给父类加载器去执行,每一层都是采用相同的方式向上委托,直到推到最顶层加载器来加载。如果父类加载器无法加载,便将加载任务退回下一级加载器去执行加载

为什么采用双亲委派,有什么好处?

jvm认定类的实例相同有两个条件,一是同一个类产生的实例,二是由同一个类加载器所加载;同一个类由不同加载器产生的实例也不相等。所以单从这点来看我们不能自动定义一个java中已经存在的类,比如定义java.lang.String,定义java.lang.Object,因为都会是由启动类加载器加载,除非采用自定义加载器的方式。

使用双亲委派模型好处:java类随着其类加载器一起具备了一种带有优先级的层次关系,例如 java.lang.Object,无论哪一个类加载器要加载该类,最终都是委托给处于顶端的启动类加载器,因此object在程序的各种类加载器环境中都是同一个类。相反如果没有使用双亲委派模型,那么假如用户自定义了一个称为java.lang.Object的类,并放在classPath中,那么系统将会出现多个不同的Object类,则java类型体系中最基础的行为都无法保证。

简单的讲双亲委派机制能很好地解决类加载的统一性问题,保证java核心库的安全性。

对一个 Class 对象来说,如果类加载器不同,即便是同一个字节码文件,生成的 Class 对象也是不等的。也就是说,类加载器相当于 Class 对象的一个命名空间。双亲委派机制则保证了基类都由相同的类加载器加载,这样就避免了同一个字节码文件被多次加载生成不同的 Class 对象的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值