欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java虚拟机中的类加载器的类型

程序员文章站 2022-04-03 10:05:24
...
所谓Java类加载器就是虚拟机用来将类加载在其内部的字节文件加载模块。Java虚拟机采用了父亲委托机制,这种机制能更好地保证Java平台的安全。在这种委托机制中,除了Java虚拟机自带的根类加载器以外,其余的类加载器都有且只有一个父加载器。加载器的加载逻辑是,加载器首先委托其父加载器去加载需要加载的类,若父加载器能够顺利加载此类,则加载工作全部交给父加载器完成,否则将由加载器自身去完成加载工作。

Java虚拟机自带的类加载器有如下三种类型:

1、根类加载器:这种加载器没有父加载器。它负责加载虚拟机的核心类库,如java.lang.*等等。同时,java.lang.Object就是由根加载器加载的。根类加载器从系统属性sun.boot.class.path所指定的目录加载类库。根类加载器的实现依赖于底层操作系统,属于虚拟机的实现一部分,它并没有继承java.lang.ClassLoader类。

2、扩展类加载器:它的父加载器是根加载器。扩展类加载器从java.ext.dirs系统属性所指定的目录加载类库,或者从JDK的安装目录的jre\lib\ext子目录下加载类库。如果将自定义的JAR文件包放在这个目录中也会自动被扩展类加载器加载。扩展类加载器是纯Java类,是java.lang.ClassLoader类的子类。

3、系统类加载器:也就是应用类加载器,它的父加载器就是扩展类加载器。它从环境变量classpath或者系统属性java.class.path所指定的目录中加载类,它是用户自定义的类加载器的默认父加载器。系统类加载器也是纯Java类,是java.lang.ClassLoader类的子类。


写了一个Java程序打印了当前系统的Java加载器的情况:


public class ClassLoadedSample{
        public static void main(String[] args){
                Class c;
                ClassLoader cl,cl1;
                cl=ClassLoader.getSystemClassLoader();
                System.out.println(cl);

                while(cl!=null){
                        cl1=cl;
                        cl=cl.getParent();
                        System.out.println(cl1+"'s parent is "+cl);
                }

                try{
                        c=Class.forName("java.lang.Object");
                        cl=c.getClassLoader();
                        System.out.println("java.lang.Object's loader is "+cl);

                        c=Class.forName("ClassLoadedSample");
                        cl=c.getClassLoader();
                        System.out.println("Sample's loader is "+cl);
                }catch(Exception e){
                        e.printStackTrace();
                }
        }
}




打印结果是:

Lab-Computer-0db2f6:JavaExercises labuser$ javac ClassLoadedSample.java
Lab-Computer-0db2f6:JavaExercises labuser$ java ClassLoadedSample
sun.misc.Launcher$AppClassLoader@1ef6a746
sun.misc.Launcher$AppClassLoader@1ef6a746's parent is sun.misc.Launcher$ExtClassLoader@535ff48b
sun.misc.Launcher$ExtClassLoader@535ff48b's parent is null
java.lang.Object's loader is null
Sample's loader is sun.misc.Launcher$AppClassLoader@1ef6a746

注意:飘红的行表示了Java虚拟机为了安全使用了null来表示根类加载器,防止黑客利用根类加载器来加载非法类,从而破坏Java虚拟机的核心代码。

同样,java.lang.Object也是由根类加载器加载的,所以显示了null值。