Java类加载器

Java类加载器在Java运行时环境中负责动态加载类到虚拟机内存。类加载过程包括加载、连接(验证、准备、解析)和初始化。系统内置BootstrapClassLoader、ExtensionClassLoader和App ClassLoader三个类加载器,遵循双亲委派模型,确保类的唯一性和稳定性。
摘要由CSDN通过智能技术生成

Java类加载器(Java Classloader)是Java运行时环境(Java Runtime Environment)的一部分,负责动态加载Java类到Java虚拟机的内存空间中。

知道类加载的过程吗?
类加载过程:加载->连接->初始化。
连接过程又可分三步:验证->准备->解析。

那么加载时这一步又做了什么?
类加载过程的第一步,主要完成下面3件事情:
1、通过全类名获取此类的二进制字节流
2、将字节流所代表的的静态存储结构转换为方法区的运行时数据结构
3、在内存中生成一个代表该类的Class对象,作为方法区这些数据的访问入口。

有哪些类加载器?
JVM中内置了三个重要的ClassLoader,除了BootstrapClassLoader 是用C++语言写的,由其他类加载器均 Java实现且全部继承自java.lang.ClassLoader :

1、BootstrapClassLoader(引导启动类加载器):
嵌在JVM内核中的加载器,是最顶层的加载器,主要负载加载JAVA_HOME/lib下的类库,引导启动类加载器无法被应用程序直接使用。

2、ExtensionClassLoader(扩展类加载器):
主要加载JAVA_HOME/lib/ext目录中的类库。它的父加载器是BootstrapClassLoader

3、App ClassLoader(应用类加载器):
App ClassLoader是应用程序类加载器,负责加载应用程序classpath目录下的所有jar和class文件。它的父加载器为Ext ClassLoader(JKD1.8之后为PlatformClassLoader)

双亲委派模型介绍

每一个类都有对应它的类加载器。系统中的ClassLoader 在协同工作的时候会默认使用双亲委派模型

即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载过的类会直接返回,否则才会尝试加载。

加载的时候,首先会把该请求委派给该父类加载器的loadClass()处理,因此所有的请求最终都应该会传送到顶层的启动类加载器BootstrapClassLoader中。当父类加载器无法处理时,才由自己来处理。当父类加载器为null,会使用启动类加载器BootstrapClassLoader

在这里插入图片描述
每个类加载都有一个父类加载器,我们可以通过程序来验证。

public class ClassLoaderTest {
    public static void main(String[] args) {
        System.out.println("1、ClassLoaderTest类的加载器" +
                ClassLoaderTest.class.getClassLoader());
        System.out.println("2、ClassLoaderTest类的父类的加载器" +
                ClassLoaderTest.class.getClassLoader().getParent());
        System.out.println("3、ClassLoaderTest类的父类的父类的加载器" +
                ClassLoaderTest.class.getClassLoader().getParent().getParent());
    }
}

在这里插入图片描述

AppClassLoader的父类加载器是PlatformClassLoader,而PlatformClassLoader为null,null并不代表PlatformClassLoader没有父类加载器,而是BootstrapClassLoader。

双亲委派模型实现源码分析
双亲委派模型代码集中在java.lang.ClassLoader的loadClass()中,相关代码如下:

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            //首先检查请求的类是否加载过
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {  //父加载器不为空,调用父加载器loadClass()方法处理
                        c = parent.loadClass(name, false);
                    } else {   //父加载器为空,使用BootstrapClassLoader加载
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found   抛出异常说明父类加载器无法完成加载请求
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order   自己尝试加载
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

双亲委派模型带来的好处是:可以避免类的重复加载,保证了Java程序的稳定运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值