Jvm加载器加载顺序

jvm的类的加载一般有如下过程:

  • 装载
  • 链接(验证,准备,解析(可选择))
  • 卸载
    关系如图:
    这里写图片描述

加载器也是个类,分为三类加载器:
- 引导加载器(用C++编写,属于JVM一部分)
- 扩展加载器
- 应用加载器
用户还可以自己定义加载器,运行一个程序系统默认的采用应用加载器,扩展加载器继承了引导加载器,应用加载器继承了扩展加载器。引导加载器会加载classpath指定路径下的jar包,一般为jre的核心jar包。在lib的ext文件夹下为扩展加载器加载的jar包。
加载一个类首先使用找父类加载器是否能加载否则才让自己加载,如果一个类里有引用,这个引用的类就从加载外层类的加载器开始寻找父类加载器。
这里写图片描述

这里写图片描述

System.out.println(Test5.class.getClassLoader().getParent());

运行结果:null
因为引导加载器是编写JVM的语言,所以无法打印出来。

System.out.println(Test5.class.getClassLoader().getParent());

运行结果:
sun.misc.Launcher$ExtClassLoader@659e0bfd
为应用加载器的父类为扩展加载器

System.out.println(Test5.class.getClassLoader());

运行结果:
sun.misc.Launcher$AppClassLoader@c387f44

打印出该类的加载器为应用加载器
- 定义两个类:

/**
 * @author micro_hz
 *
 */
//分别打印出两个类的加载器
public class Test1 {
    public static void main(String args[])
    {
        System.out.println(Test5.class.getClassLoader());
        Test2 t = new Test2();
        t.printClassLoader();
    }
}
/**
@author:micro_hz
2015年8月8日
 */
public class Test2 {
    public void printClassLoader()
    {
    System.out.println(this.getClass().getClassLoader());
    }
}

运行结果:

sun.misc.Launcher$AppClassLoader@c387f44
sun.misc.Launcher$AppClassLoader@c387f44

果然都是采用应用加载器加载的。
将Test2jar包放在扩展ext文件夹下,Test1不放。运行结果:

sun.misc.Launcher$AppClassLoader@73d16e93
sun.misc.Launcher$ExtClassLoader@33909752

Test1从应用加载器从扩展加载器没找到,则直接从应用加载器加载, 引用的Test2也从应用加载器开始请求扩展加载器找到了加载类,因此运行为此结果。
然后我们将Test1打为jar包放在jre\lib\ext 目录下,将Test2jar不放在ext和classes包里。
运行结果为:

sun.misc.Launcher$ExtClassLoader@7852e922
Exception in thread "main" java.lang.NoClassDefFoundError: Test2
    at dataStrutcure.Test1.main(Test1.java:13)
Caused by: java.lang.ClassNotFoundException: dataStrutcure.Test2
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 1 more

因为Test1加载的时候首先从应用加载器找到父类加载器扩展加载器,发现在扩展器可以加载,然后再请求引导加载器,发现不能加载,所以最后由扩展加载器加载。在Test1中应用了Test2,由于Test1是由扩展加载器加载的,因此Test2直接从扩展加载开始请求引导加载器发现不能加载,因此尝试从扩展加载器加载,发现不能加载因此抛出ClassNotFound异常。
如果我们把Test2也jar包放在ext就会都从扩展加载器加载了:

sun.misc.Launcher$ExtClassLoader@7852e922
sun.misc.Launcher$ExtClassLoader@7852e922

关于类加载的路径请点击这里
相关引用这里写链接内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值