类加载的过程中,不同类加载器的加载路径测试

我们知道JVM加载类的过程遵循“双亲委派机制”,每当JVM启动时,是通过一个ClassLoader来加载class文件的。

ClassLoader有三个实现,分别是:BootstrapLoader,ExtClassLoader和AppClassLoader.

三个类加载器的作用不同,所加载的class文件也不相同。

下面我们通过代码实现查看三个类加载器分别所加载的class路径

/**
 *
 * @author JJ_knows
 *
 */
public class ClassLoaderTest {
    public static void main(String[] args) {
        System.out.println("启动类加载器加载的类:");
        String bootPath = System.getProperty("sun.boot.class.path");//启动类加载器所加载的是JVM中最底层的类,加载时的搜索路径是sun.boot.class.path。
        System.out.println(bootPath.replaceAll(";",System.lineSeparator()));
        System.out.println("......................");
        System.out.println("扩展类加载器加载的类:");
        String extPath = System.getProperty("java.ext.dirs");//扩展类加载器是用来加载java的一些库的,加载时的搜索路径是java.ext.dirs
        System.out.println(extPath.replaceAll(";",System.lineSeparator()));
        System.out.println("......................");
        System.out.println("应用类加载器加载的类:");
        String appPath = System.getProperty("java.class.path");//应用类加载器搜索路径是java.class.path
        System.out.println(appPath.replaceAll(";",System.lineSeparator()));
    }
}

 

输出结果:

启动类加载器加载的类:
D:\jdk8\Java\jdk1.8.0_162\jre\lib\resources.jar
D:\jdk8\Java\jdk1.8.0_162\jre\lib\rt.jar
D:\jdk8\Java\jdk1.8.0_162\jre\lib\sunrsasign.jar
D:\jdk8\Java\jdk1.8.0_162\jre\lib\jsse.jar
D:\jdk8\Java\jdk1.8.0_162\jre\lib\jce.jar
D:\jdk8\Java\jdk1.8.0_162\jre\lib\charsets.jar
D:\jdk8\Java\jdk1.8.0_162\jre\lib\jfr.jar
D:\jdk8\Java\jdk1.8.0_162\jre\classes
......................
扩展类加载器加载的类:
D:\jdk8\Java\jdk1.8.0_162\jre\lib\ext
C:\Windows\Sun\Java\lib\ext

......................
应用类加载器加载的类:

D:\jdk8\Java\jdk1.8.0_162\jre\lib\resources.jar
D:\jdk8\Java\jdk1.8.0_162\jre\lib\rt.jar
D:\personal\readTemplateDemo\lbgw-web\target\test-classes
D:\personal\readTemplateDemo\lbgw-web\target\classes

D:\repository\org\apache\logging\log4j\log4j-api\2.7\log4j-api-2.7.jar
D:\repository\org\apache\logging\log4j\log4j-core\2.7\log4j-core-2.7.jar
D:\ideaIU-2017.2.win\lib\idea_rt.jar

双亲委派机制的加载过程是如何实现的呢?

ClassLoader中有一个 loadClass()方法,我们进入这个方法查看:

我们可以看到加载类时,首先通过:应用类加载器->扩展类加载器->启动类加载器的顺序 ,从下到上的依次进行检查,看是否已经被加载。如果已经被加载,则直接返回。

如果并未被加载过:

 ExtClassLoader 和AppClassLoader 等类加载器,通过重写这个findClass()方法,实现对不同路径下的类进行加载。

由此可知,当我们自定义类加载器的时候,只需集成ClassLoader并重写这个方法即可。

(注意这里采用的设计模式: 模板方法。)

为何要采用双亲委派机制,它的作用是什么呢?

1. 避免了重复加载

2.出于安全考虑,保证了java核心类不被篡改。

那可不可以打破“双亲委派机制”?如何打破?

很简单,只需要重写loadClass()方法就可以了。

 

 

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读