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加载器的情况:
打印结果是:
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值。
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值。