深入理解Java类加载器的作用

介绍与作用

当我们编写Java代码后并进行编译,会在当前项目目录下生成一个target文件夹。我们可以发现我们同一个类文件从.java结尾的后缀变为了.class结尾的后缀。

那么为什么我们的编译器要把.java文件变为.class结尾的文件呢?

Java代码经过编译器编译后会将.java文件变为.class结尾的文件,这是因为编译后的.class文件是二进制文件。这种字节码文件(.class文件)是一种中间表示形式,它不是直接在硬件上执行的机器代码,而是一种可以被 Java 虚拟机(JVM)读取和执行的格式(JVM无法直接识别.java文件),并使用即时编译器(JIT)将它们转换成特定平台的机器代码,然后执行。

那么类加载器就可以根据类的对应的全限定类名去找到这个文件并装载.class文件,然后将这个文件导入到JVM中的运行时数据区。

类加载器的种类

我们常用的类加载器一般来说有四种

启动类加载器(Bootstrap ClassLoader)

BootStrap ClassLoader 它是负责加载JAVA_HOME/jre/lib目录下的类,他它由C++语言编写。

在Java源码中,并没有一个具体的类来表示启动类加载器,它是JVM中的一部分,由JVM实现并且不继承java.lang.ClassLoader。它主要负责加载JDK中自有的类。

扩展类加载器(Extension ClassLoader)

在Java虚拟机中,扩展类加载器通常是由java.ext.dirs系统属性指定的目录中的类加载器实现的。在Java源码中,对应的类是sun.misc.Launcher$ExtClassLoader。继承父类java.lang.ClassLoader。

应用程序类加载器(Application ClassLoader)

应用程序类加载器通常是由系统属性java.class.path指定的类路径中的类加载器实现的。在Java源码中,对应的类是sun.misc.Launcher$AppClassLoader。它主要负责加载我们自己开发中定义的类和pom文件中引入的依赖或者jar包中的类。继承父类java.lang.ClassLoader。

自定义加载类

自定义类加载器,实现自定义类加载规则。

类的双亲委派原则

介绍

双亲委派原则的作用是  : 一个类只会被加载一次,防止一个类多次重复的加载,保证了类的唯一性。防止开发者私自篡改JDk提供的类中的Api。

package com.qjc;

/**
 * @Auther: Qu Jingchuan
 * @Date: 2024/5/17 12:27
 * @Description: 测试类加载器对同一个类加载时可能出现篡改原有api的问题
 */
public class String {
    public static void main(String[] args) {
        System.out.println("1111111111111111");
    }
}

运行后报错

这是因为String这个类已经被启动类加载器加载过了,当用户自定义String后重复加载,并且JDK中提供的类中没有main方法因此会出现错误。

由于是双亲委派的机制,java.lang.String的在启动类加载器得到加载,因为在核心jre库中有其相同名字的类文件,但该类中并没有main方法。这样就能防止恶意篡改核心API库。 

总结双亲委派机制

加载某一个类,先委托上一级的加载器进行加载,如果上级加载器也有上级,则会继续向上委托,如果该类委托上级没有被加载,子加载器尝试加载该类。

虽然名字叫双亲委派机制,但是并不是继承关系,而是委派关系。当来了一个类信息后。

加载某一个类,先委托上一级的加载器进行加载,如果上级加载器也有上级,则会继续向上委托,如果该类委托上级没有被加载,子加载器尝试加载该类。

例如有一个Student类,会先让应用程序类加载器加载,然后应用程序类加载器(不管能不能加载都会先向上委派)。扩展类加载器同理继续向上委派,直到到达启动类加载器。启动类加载器判断这个Student类能不能被自己加载,很显然不是jdk中定义的类无法加载,因此向下给扩展类加载器尝试加载,但是也无法加载。由于只能应用程序类加载器加载,于是应用程序类加载器会加载这个类。 

作用: 

1. 通过双亲委派机制可以避免某一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性。

2. 为了安全,保证自有类库中的API不会被随意的修改。 

  • 36
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值