JVM 类加载器

Java中的类加载器分为两种,一种Java 自带的类加载器,另一种是用户自定义的类加载器

将分配好的字节码文件分配给内存时,需要使用到类加载器。如图所示在这里插入图片描述

Java自带的类加载器分为三种

一、启动类加载器(根类加载器)

负责加载:$JAVA_HOME 中jre/lib/rt.jar里所有的class(由Sun公司写好的类,如String,File等),由C++实现,不是ClassLoader子类,所以启动类加载器没有父类加载器,它没有父类加载器。但是它是扩展类加载器的父类加载器

 public static void main(String[] args) throws ClassNotFoundException {
 		// 获取根类加载器,此结果的输出是null,因为在java中,
 		// 默认使用返回null代表使用根类加载器
        Class<?> clazz = Class.forName("java.lang.String");
        System.out.println(clazz.getClassLoader());
    }
二、扩展类加载器

负责加载:负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包(加载的都是jdk内部自己使用的类。),它的父类加载器是启动类加载器,但是你要验证的话,他会输出为null,也就是说在java类加载器中,null代表了启动类加载器。

三、应用类加载器(系统类加载器)

负责加载:负责加载classpath中指定的jar包及目录下class。(包括程序员编写的类)。它的父类加载器是扩展类加载器。

 public static void main(String[] args) throws ClassNotFoundException {
		// 获取应用类加载器,此结果输出的是
		// sun.misc.Launcher$AppClassLoader@14dad5dc,
		// 代表的是加载该类的是应用类加载器
        Class<?> clazz2 = Class.forName("com.jvm.dlassLoader.C");
        System.out.println(clazz2.getClassLoader());
    }

类加载机制

如图所示,该图显示了java使用双亲委托加载机制
该图更详细的说明了双亲委托机制的加载方法

接下来,看一下什么是双亲委托机制

双亲委托机制

定义:简单的说,当一个类需要加载时,类加载器总是先去让父类加载器去进行加载此类,如果父加载器可以完成类加载任务,就成功返回;当父类加载器不能加载此类时,则该类加载进行加载。
好处:

  1. 可以确保Java核心库的类型安全:所有的Java应用都至少会引用java.lang.object类,也就是所在运行期,java.lang.Object这个类会被加载到Java虚拟机中;如果这个加载过程是由Java应用自己的类加载器所完成的,那么很可能就会在JVM中存在多个版本的java.lang.Object类,而且这些类之间还是不兼容的,相互不可见的(正是命名空间在发挥着作用)。借助于双亲委托机制,Java核心类库中的类的加载工作都是由启动类加载器来统一完成,从而确保了Java应用所使用的都是同一个版本的额java核心类库,他们之间是相互兼容的。
  2. 可以确保Java核心类库所提供的类不会被自定义的类所替代
  3. 不同的类加载器可以为相同名称的类创建额外的命名空间。相同名称的类可以并存在Java虚拟机中,只需要用不同的类加载器来加载他们即可。不同类加载器所加载的类之间是不兼容的忙着就相当于在Java虚拟机内部创建了一个又一个相互隔离的Java类空间,这种技术在很多框架中得到了实际应用。

打破双亲委托机制

1. 为什么要打破

个人认为:因为子类加载器可以使用父类加载器所加载的类(简单地说就是能看到父类加载器加载的类),并且越基础的类就越由上层的加载器加载,所以这就保证了我们可以放心的调用他们的基础类(Api)。但是,会有特殊情况。例如:
一个典型的例子就是JNDI服务,JNDI现在已经是Java的标准服务,
它的代码由启动类加载器去加载(在JDK1.3时放进去的rt.jar),但JNDI的目的就是对资源进行集中管理和查找,它需要调用由独立厂商实现并部署在应用程序的ClassPath下的JNDI接口提供者的代码,但启动类加载器不可能“认识”这些代码。
为了解决这个问题,Java 引用了线程上下文类加载器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值