在做Java开发时了解Java类加载机制是非常好的。而对类加载机制的基本理解对Java开发人员处理类加载器(ClassLoader)相关的异常也很有帮助。
类加载器委托机制
Java类的装载是通过类加载器(CL)来完成的,这些类加载器负责将类加载到JVM中。简单的应用可以使用java平台自带的类加载器来加载自身的类,而稍微复杂一些的应用则倾向于自定义类加载来加载自身的类。
在java中类加载器是以树状结构组织的。通过请求一个类加载器并通过在其缓存中查找来确定某个类是否已被加载。如果在缓存中已经有该类,那么CL直接返回;否则,该类加载器委托其父类加载器来加载该类。如果这个类加载器没有父类或者父类不能加载这个类则会抛出ClassNotFoundException异常,此时被请求的类加载器会尝试去在它自身的路径下来查找并加载需要被加载类的类文件。如果找到了这个类,就将其返回;否则会抛出ClassNotFoundException异常。其中缓存的查找方式为递归的从子类到父类查找,直到到达树(译注:类加载器已树状结构组织)的根节点或者在缓存中找到需要的类为止。如果缓存搜索已到达根节点,则类加载器会从父类到子类再次展开递归来加载需要的类。总的来说顺序如下:
1. 缓存
2. 父类
3. 子类
这种机制确保类会类会被最接近根结点的类加载器加载。请谨记,父类加载器总是有优先加载类的权限。而这很重要的作用就是确保核心java类都被bootstrap类加载器加载,这个类加载器是用来保证正确版本的类加载,如java.lang.Object。此外,bootstrap类加载器还保证一个类加载只能看到自身或其父类(或父类的父类等)加载的类,而不能看到其子类以及兄弟类(译注:继承同一个父类的类称为兄弟类)所加载的类。
下图阐明了类加载器的层级关系。根加载器是bootstrap类加载,该加载器是通过native方法实现,并且不能在java代码中实例化。
BootStrap之后便是扩展类加载器,该加载器的主要责任是从扩展目录中加载类并且在新的JVM中不修改用户classpath的情况下来提供简单访问JVM扩展的能力。而系统或者应用类加载器则负责从环境变量CLASSPATH中指定的路径来加载类;这种类加载器可以通过调用ClassLoader.getSystemClassLoader()方法获得。
类加载阶段
具体的类加载可以分为3个阶段:物理加载,链接,初始化。
1 在物理加载阶段,要求类可以在指定的classpath路径中被找到。如果可以找到类文件,通过读取类文件来加载字节码。这个处理过程给出了单个类对象的一个基本内存结构,但是像方法、字段以及对以其他类的一些引用这些概念在这个阶段是不知道的。
2 链接阶段可以拆分为3个主要阶段,因为这个阶段比较复杂:
2.1 通过类加再起校验字节码,该过程会在字节码上执行一系列校验。
2.2 类准备。这个阶段准备必要的数据结构,表示类中所定义的字段、方法以及所实现的接口。
2.3 解析某个特定类中所有的其他类引用。类可以通过很多途径被应用,具体如下
2.3.1 父类
2.3.2 接口
2.3.3 字段类型
2.3.4 方法返回值类型
2.3.5 在方法中使用的本地变量类型
3 在初始化阶段,这个类中包含的所有初始化块都会被执行,一遍静态变量都会被初始化为默认值。
有趣的是类加载可以通过延迟加载机制来实现,因此一部分只是在第一次使用的时候才被加载而不是一开始就加载。
异常
在处理类加载问题时最大的挑战在于问题很难在类加载这个处理过程体现出来,而是在之后使用这个类的时候才会被体现出来。以下是类加载时两个相关的异常以及造成对应异常的可能原因:
ClassNotFoundException
l 当被加载的类相关文件、目录或者其他资源没有添加到对应了类加载器或者父类加载器时
l 当类加载器的父类设置错误时
l 当类加载器使用错误时
NoClassDefFoundError
l 当被加载的类相关文件、目录或者其他资源没有添加到对应了类加载器或者父类加载器时
l 当类加载器的父类设置错误时
l 当一个类被加载时,该类中所包含的引用对该类的类加载器不可达时,例如加载器的子类
1. 本文由程序员学架构翻译
2. 本文译自 http://www.techjava.de/topics/2008/01/java-class-loading/
3. 转载请务必注明本文出自:程序员学架构(微信号:archleaner )
4. 更多文章请扫码:
相关推荐
此外,我们还会探讨Java程序的类加载器和双亲委派机制,以及自定义类加载器和类卸载的实现原理和应用方法。 总的来说,本资源将为Java程序员提供全面的Java字节码和类加载原理和实践经验。通过学习本资源,开发人员将...
深入理解和探究Java类加载机制—- 1.java.lang.ClassLoader类介绍 ... Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。 引导类加载器(bootstrap class loade
:)的类型深入 81 话题14 井然有序——运算顺序的详细挖掘 86 话题15 异曲同工——交换变量的3种方式 90 话题16 择木而栖——开关选择表达式switch的类型内幕 95 第3章 String类 103 话题17 来龙去脉——“+”是怎样...
对java的类加载机制,进行了深入的解析,并详细的实现了客户化加载器。
1.类加载 在java代码中,类型的加载、连接与...将类的.class文件的二进制数据读入到内存中,将其放在运行时数据的方法区内,然后在内存中创建一个java.lang.Class用来封装类在方法区内的数据结构(java规范并未说明Cl
第二部分是7-13章,对JVM、Java源代码和字节代码操作、类加载器、对象生命周期、多线程、并发编程、泛型、安全等Java平台的核心技术进行了深入解析,掌握这部分内容有助于深入理解Java的底层原理;第三部分为第14章...
主要介绍了Java中的类加载器,是Java入门学习中的基础知识,需要的朋友可以参考下
《链接器和加载器》首先通过实例深入浅出地阐述了在不同的编译器和操作系统中链接和加载过程的差异。在这个基础上,作者提出了清晰实用的忠告,来帮助你创建更快、更清晰的代码。你将会学习如何规避和Windows DLL...
第二部分是7-13章,对JVM、Java源代码和字节代码操作、类加载器、对象生命周期、多线程、并发编程、泛型、安全等Java平台的核心技术进行了深入解析,掌握这部分内容有助于深入理解Java的底层原理;第三部分为第14章...
虚拟机类加载机制 / 171 7.1 概述 / 171 7.2 类加载的时机 / 172 7.3 类加载的过程 / 176 7.3.1 加载 / 176 7.3.2 验证 / 178 7.3.3 准备 / 181 7.3.4 解析 / 182 7.3.5 初始化 / 186 7.4 类加载器 ...
类加载器2.1 类加载器种类2.1.1 Java虚拟机自带的类加载器2.1.2 用户自定义的类加载器2.2 双亲委派机制2.2.1 为什么要有双亲委派机制2.2.2 可不可以自定义一个String/Object类?2.3 破坏双亲委派2.3.1 为何要破坏...
类加载器的高级特性(自定义类加器实现加密解密) iBATIS开源主流框架(实现半自动化hibernate) 企业实用技能之详解(眼睛横纹模式验证码防止恶意登陆) 动态页面的静态化处理 图片上传技术 在springMVC中实现原始的Excel...
7.4.1 类与类加载器 7.4.2 双亲委派模型 7.4.3 破坏双亲委派模型 7.5 本章小结 第8章 虚拟机字节码执行引擎 8.1 概述 8.2 运行时栈帧结构 8.2.1 局部变量表 8.2.2 操作数栈 8.2.3 动态连接 8.2.4 方法...
1.10 xml处理器/解析器 35 1.11 小结 36 第2章 xml名称空间 38 2.1 声明名称空间 38 2.2 名称空间在元素和属性中的运用 39 2.2.1 名称空间在元素中的运用 39 2.2.2 默认名称空间 41 2.2.3 名称空间在属性中...
加载器、对象生命周期、多线程、并发编程、泛型、安全等Java 平台的核心技术进行了深 入解析,掌握这部分内容有助于深入理解Java 的底层原理;第三部分为第1 4 章,是对Java 8 的展望,简要介绍了Java 8 中将要...
1.10 xml处理器/解析器 35 1.11 小结 36 第2章 xml名称空间 38 2.1 声明名称空间 38 2.2 名称空间在元素和属性中的运用 39 2.2.1 名称空间在元素中的运用 39 2.2.2 默认名称空间 41 2.2.3 名称空间在属性中...
主要介绍了Java中的Classloader的运行机制,包括从JVM方面讲解类加载器的委托机制等,需要的朋友可以参考下
1.10 xml处理器/解析器 35 1.11 小结 36 第2章 xml名称空间 38 2.1 声明名称空间 38 2.2 名称空间在元素和属性中的运用 39 2.2.1 名称空间在元素中的运用 39 2.2.2 默认名称空间 41 2.2.3 名称空间在属性中...
Java 虚拟机面试题全面解析,《深入理解Java虚拟机》干货版,自己总结,希望能够帮助大家,免费下载~什么是类加载机制? 虚拟机和物理机的区别是什么? 运行时栈帧结构 Java方法调用 什么是方法调用? Java的方法调用,...