一文读懂java的双亲委派机制

1、你知道java的双亲委派机制吗

2023/7/19 23:07:52

    在Java中,类加载器采用了双亲委派模型来保证类的加载安全和一致性。

根据双亲委派机制,当一个类加载器收到加载类的请求时,它首先将这个请求委派给父类加载器去尝试加载。只有在父类加载器无法加载该类的情况下,子加载器才会尝试自己去加载类。

这种层级关系一直延续到顶层的启动类加载器(Bootstrap Class Loader)。启动类加载器是由JVM内部实现的,它负责加载Java的核心类库,如java.lang包以及其他基础类。如果父类加载器无法加载某个类,那么子类加载器才会尝试加载,这样可以确保类的加载过程是由上到下的。

通过双亲委派机制,Java能够避免类的重复加载,保证类的一致性,并提高了安全性。

2、什么情况下,类加载器会加载类

2023/7/19 23:11:18

类加载器在以下情况下会收到加载类的请求:

  1. 当Java程序通过类的全限定名(Fully Qualified Name)引用一个类时,例如使用new关键字创建对象、调用静态方法或访问静态字段时,类加载器就会被触发加载相应的类。

  2. 当通过反射机制(Reflection)动态地加载类时,也会触发类加载器加载类的请求。

  3. 当一个类引用了另一个类,而这个被引用的类尚未被加载时,类加载器也会被触发加载被引用的类。

  4. 当运行第三方库或框架时,类加载器会负责加载这些库或框架所依赖的类。

需要注意的是,每个类加载器都有自己的命名空间,因此不同的类加载器可以加载同名但是来源不同的类。当一个类加载器收到加载类的请求时,它会首先查询自己的命名空间中是否已经加载过该类,如果没有则委托给父类加载器。这样一层层地向上委派,直到顶层的启动类加载器。只有当所有父类加载器都无法加载该类时,才由当前类加载器尝试加载。这种机制确保了类的加载是一致且有序的。

2023/7/19 23:13:03

3、加载类是什么意思,什么是类加载器

2023/7/19 23:13:24

    加载类指的是将类的字节码文件(或者其他形式的类定义)加载到Java虚拟机(JVM)中,并转换为可执行的Java类对象(计算机指令)的过程。在运行Java程序时,JVM需要根据需要动态地加载类来执行相关操作。

类加载器(ClassLoader)是Java虚拟机(JVM)的一部分,它负责动态加载类及相关资源文件到内存中,并生成对应的类对象。类加载器可以通过类的全限定名来寻找和加载类的字节码文件,并将其转化为JVM可以理解和执行的形式。

在Java中,有三种主要的类加载器:

  1. 启动类加载器(Bootstrap Class Loader):它是JVM的一部分,负责加载Java的核心类库,如java.lang包等。它是最顶层的类加载器,在JVM启动时就已经被创建。

  2. 扩展类加载器(Extension Class Loader):它是由启动类加载器的子类加载器,负责加载Java的扩展库,位于jre/lib/ext目录下的JAR包。它主要加载Java的标准扩展API和一些第三方扩展API。

  3. 应用程序类加载器(Application Class Loader):也被称为系统类加载器,它是加载应用程序自身的类和资源文件的加载器。它负责加载应用程序类路径(Classpath)上指定的类和资源。

除了这三种主要的类加载器,还可以通过编写自定义的类加载器来加载特定位置或特定形式的类。

类加载器的主要作用是实现类的加载、链接和初始化等任务,确保类在运行时能够被正确加载并可用于创建对象和执行代码。它还提供了类加载的双亲委派机制,保证类的一致性和安全性。

2023/7/19 23:16:54

4、类的字节码文件是指编译后的.class文件吗

2023/7/19 23:17:01

是的,类的字节码文件指的就是编译后的.class文件。在Java中,源代码经过编译器将其转换为字节码文件,这些字节码指令可以被Java虚拟机(JVM)执行。

每个Java类都会对应一个字节码文件,该文件包含了类的方法、字段和其他相关信息。当Java程序需要使用某个类时,JVM会通过类加载器将对应的字节码文件加载到内存中,并生成可执行的Java类对象,以供程序运行时使用。因此,字节码文件是Java程序在运行过程中必不可少的一部分。

2023/7/19 23:18:19

5、自定义一个类时,怎么知道它的加载器是哪个

2023/7/19 23:18:27

在Java中,可以通过调用类的getClassLoader()方法来获取加载该类的类加载器。这个方法是定义在java.lang.Object类中的,所以任何一个Java对象都可以调用该方法,返回它的类加载器。

例如,假设有一个名为MyClass的自定义类,可以使用以下方式获取它的类加载器:

javaCopy CodeClassLoader classLoader = MyClass.class.getClassLoader(); 

上述代码将返回一个ClassLoader对象,表示加载MyClass类的类加载器。如果返回null,则表示使用的是引导类加载器(Bootstrap Class Loader)加载的类。

需要注意的是,对于使用引导类加载器加载的类,无法通过普通的Java代码获取到其类加载器,因为引导类加载器并不是一个普通的Java对象。

在大多数情况下,自定义类的加载器都是应用程序类加载器(Application Class Loader)或其父加载器(如扩展类加载器)。

2023/7/19 23:26:16

5、双亲委派机制可以通过代码演示吗?
public class ClassLoaderDemo {
        public static void main(String[] args) {
            // 获取系统类加载器(应用程序类加载器)
            ClassLoader appClassLoader = ClassLoader.getSystemClassLoader();
            System.out.println("appClassLoader  is : " + appClassLoader);
            try {
                // 尝试使用应用程序类加载器加载自定义类(加载成功)
                Class<?> customClass = appClassLoader.loadClass("com.chenchen.entity.Person");
                System.out.println("Person class is loaded by: " + customClass.getClassLoader());
                // 尝试使用扩展类加载器加载自定义类(加载失败)
                ClassLoader extClassLoader = appClassLoader.getParent();
                System.out.println("appClassLoader Parent is : " + extClassLoader);
                Class<?> customClass2 = extClassLoader.loadClass("com.chenchen.entity.Person");
                System.out.println("Person class is not loaded by: " + customClass2.getClassLoader());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

输出结果:

appClassLoader  is : sun.misc.Launcher$AppClassLoader@18b4aac2
Person class is loaded by: sun.misc.Launcher$AppClassLoader@18b4aac2
appClassLoader Parent is : sun.misc.Launcher$ExtClassLoader@34c45dca
java.lang.ClassNotFoundException: com.chenchen.entity.Person
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
    at com.chenchen.ClassLoaderDemo.main(ClassLoaderDemo.java:20)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值