ClassLoader工作机制

本文详细介绍了Java中的ClassLoader机制,包括其父优先的等级加载原理、类加载过程中的关键步骤,以及如何通过自定义ClassLoader实例化对象。同时,还讨论了类加载的两种方式:隐式加载与显式加载,并分析了常见的类加载错误。

 

095347_GHWG_2290420.png

ClassLoader除了能将Class加载到JVM中以外,还有一个重要的作用就是审查每个类应该由谁加载,它是一种父优先的等级加载机制。

此外,ClassLoader也会将Class字节码重新解析成JVM统一要求的对象格式。

ClassLoader类结构分析

094633_Yjr2_2290420.png

defineClass 方法用来将byte字节流解析成JVM能够识别的Class对象。有了这个方法意味着我们不仅仅可以通过class文件实现实例化对象,还可以通过其他方式实例化对象,如果我们通过网络接收到一个类的字节码,就可以拿这个字节码流直接创建类的Class对象形式化实例对象。

注意,如果直接调用这个方法生成类的Class对象,这个类的class对象还没有resolve,这个resolve将会在这个对象真正实例化的时候才进行。

ClassLoader的等级加载机制

095327_IlHX_2290420.png

整个JVM平台提供三层ClassLoader,这三层ClassLoader可以分为两种类型,可以理解为为接待室服务的接待室和为会员服务的接待室两种。

(1) Bootstrap ClassLoader,这个ClassLoader就是接待室服务自身的,它主要加载JVM自身工作需要的类,这个ClassLoader完全是由JVM自己控制的,需要加载哪个类,怎么加载都有JVM自己控制,别人也访问不到这个类,所以这个ClassLoader是不遵守前面介绍的加载规则的,它仅仅是一个类的加载工具而已,既没有更高一级的父加载器,有没有子加载器。

(2) ExtClassLoader,这个类加载器有点特殊,它是JVM自身的一部分,但是它的血统也不是很纯正,它并不是JVM亲自实现的。我们可以理解为这类加载器是那些与这个大会合作单位的员工会员,这些会员既不是JVM内部的,也和普通的外部会员不同,所以就由这个类加载器来加载。它服务的特定目标在System.getProperty("java.ext.dirs")目录下。

(3) AppClassLoader,这个类加载器就是专门为接待会员服务的,它的父类是ExtClassLoader。它服务的目标是广大普通会员,所有在System.getProperty("java.class.path"); 目录下的类都可以被这个类加载器加载,这个目录就是我们经常用到的classpath。

应用中类加载器的等级层次。

095716_2NFK_2290420.png

ExtClassLoader的父类也不是Bootstrap ClassLoader ,ExtClassLoader并没有父类,我们在应用中能提取到的顶层父类是ExtClassLoader。

 

JVM加载Class文件到内存中的两种方式

隐式加载:

所谓隐式加载就是不通过在代码里调用ClassLoader来加载需要的类,而是通过JVM来自动加载需要的类到内存的方式。例如,当我们在类中继承或者引用某各类时,JVM在解析当前这个类时发现引用的类不在内存中,那么就会自动将这些类加载到内存中。

显式加载:

相反的显示加载就是我们在代码中通过调用ClassLoader类来加载一个类的方式,例如,调用

this.getClass.getClassLoader().loadClass()或者Class.forName(),或者我们自己实现的ClassLoader的findClass()方法等。

其实这两种方式是混合使用的,例如,我们通过自定义的ClassLoader显示加载了一个类时,这个类中又引用了其他类,那么这些类就是隐式加载的。

 

如何加载class文件

ClassLoader加载一个class文件到JVM时需要经过的步骤

102410_6Zpx_2290420.png

第一个阶段:找到.class文件并把这个文件包含的字节码加载到内存中。

第二个阶段:又可以分为三个步骤,分别是字节码验证,Class类数据结构分析及相应的内存分配和最后的符号表的链接。

第三个阶段:类中静态属性和初始化赋值,以及静态块的执行等。

常见加载类错误分析

在执行Java程序时经常会碰到ClassNotFoundException和NoClassDefFoundError两个异常,它们都和类加载有关。

转载于:https://my.oschina.net/aslanjia/blog/1509551

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值