JVM类加载器及类加载机制

类加载器分为JVM自带的类加载器和用户自定义的类加载器。

一、JVM自带的类加载器又分为以下三种

启动类加载器(bootstrap)、扩展类加载器、应用(系统)类加载器。

其中启动类加载器负责加载$JAVA_HOME\jre\lib路径下的类(常见的比如rt.jar文件,比如java.lang.Object);

JVM类加载器及类加载机制_第1张图片

扩展类加载器负责加载$JAVA_HOME\jre\lib\ext路径下的类(比如com.sun.nio.zipfs.ZipUtils);

JVM类加载器及类加载机制_第2张图片

应用类加载器负责加载用户当前类路径下的类(通常是我们自己写的类或者第三方依赖包中的类)。

这三种类加载器有层级关系。应用类加载器的父级是扩展类加载器,扩展类加载器的父级是启动类加载器。

为了说明这点,我们可以自己编写一个类TestClass,然后再该类中加入以下main方法。

JVM类加载器及类加载机制_第3张图片

其运行结果如下:

JVM类加载器及类加载机制_第4张图片

    

一个类进行加载的大概过程是这样的,首先会从缓存中查找是否加载过该类,如果有,则直接使用,如果没有则会委托给父类加载器,父类加载器会继续委托给父类加载器,直到启动类加载器(也即bootstrap ClassLoader),如果启动类加载器没有找到,则会由扩展类加载器进行查找,如果仍未找到,才会由应用类加载器进行查找。这种机制有一个好处就是可以保证类仅仅被加载一次。

    为了说明这一点我们可以自己编写个简单例子验证下,先建个包名为java.lang,然后再新建个类叫String。然后再里面写个main方法,然后启动。如下图,启动时就报错了。因为启动程序会默认查找String.class对象,首先会由启动类加载器查找,结果找到了,因为JDK自带该类,在rt.jar文件中。但该类中并无main方法,所以会报错。也就是说在当前条件下,我们自己写的这个类是不会得到加载的。

JVM类加载器及类加载机制_第5张图片

 

二、用户自定义的类加载器

主要是用户自定义一个类,然后继承java.lang.ClassLoader。

JVM类加载器及类加载机制_第6张图片

你可能感兴趣的:(JVM)