在做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 ...
### Java类加载器详解 Java类加载器是Java运行时环境的一个关键组成部分,负责将类文件(.class)从各种来源加载到JVM中。它不仅管理类的生命...掌握类加载器的工作机制对于深入理解Java应用的运行时行为至关重要。
总的来说,自定义Java类加载器是深入理解和控制JVM行为的重要手段,它可以让我们在程序设计中实现更高级别的灵活性和定制性。通过`MyClassLoader`,你可以按照个人需求来调整类的加载策略,进一步提升软件系统的功能...
Java中的类加载器遵循一个原则叫做“父母委托模型”,即当一个类加载器收到类加载请求时,首先将加载任务委托给父类加载器,只有当父类加载器无法完成加载时才会尝试自己加载。 这种设计模式的好处在于避免了类的...
本文主要解析Java类加载的原理,分为三个部分:基础的类加载原理解析、插件环境下的类加载和线程上下文类加载器。 首先,Java虚拟机(JVM)内置了三种预定义的类加载器: 1. 启动(Bootstrap)类加载器:这是最基础的...
【深入探讨 Java 类加载器】 Java 类加载器是Java虚拟机(JVM)的核心组成部分,它的主要任务是将Java类的字节码加载到JVM中以便执行。类加载器的概念始于JDK 1.0,最初是为了解决Java Applet在浏览器中的运行需求...
Java的类加载器是Java虚拟机(JVM)的核心组件之一,它负责将类的字节码文件从文件系统或网络中加载到JVM中,然后进行校验、解析和初始化,使得Java程序能够运行。类加载器的概念是Java动态加载和运行时类重定义的...
本文将详细解析Java类加载原理,分为三篇文章进行阐述,分别是:Java类加载原理解析、插件环境下类加载原理解析和线程上下文类加载器。 首先,我们来了解Java虚拟机(JVM)的类加载器结构。JVM预定义了三种主要的类...
通过掌握类加载的过程、类加载器的工作原理以及类加载的线程安全性等方面的知识,开发者能够更好地利用Java的动态特性,优化程序性能,并避免常见的异常问题,如`ClassNotFoundException`等。此外,对于自定义类加载...
### 深入探讨Java类加载器 #### 类加载器基本概念 类加载器(Class Loader)是Java语言的关键组成部分之一,它负责将Java类的字节码加载到Java虚拟机(JVM)中,从而使得Java应用程序能够运行起来。自Java诞生以来...
Java类加载器是Java虚拟机(JVM)的重要组成部分,它的主要职责是将类的字节码文件(.class文件)从文件系统、网络或内存中读取,并转换为运行时的java.lang.Class对象。这个过程是Java动态加载机制的核心,使得Java...
总之,Java类加载器机制是Java平台灵活性和动态性的重要体现,它使得JVM能够在运行时加载和解析类,支持代码的热部署,增强了系统的可扩展性和可维护性。通过深入学习和理解这一机制,开发者能够更好地驾驭Java应用...
了解Java类加载器的工作原理,可以帮助开发者更加深入地掌握Java程序的执行机制,同时也对排查类加载相关的故障(如类找不到、类重复加载等问题)提供帮助。在实际开发中,合理使用自定义类加载器,可以实现热部署、...
理解类加载器的工作原理对于深入学习Java平台、优化应用程序性能以及实现自定义加载器至关重要。 1. **类加载器层次结构** Java中的类加载器分为三个主要层次:启动类加载器(Bootstrap ClassLoader)、扩展类加载...
《深入Java虚拟机(七)深入源码看java类加载器ClassLoader》 Java类加载器(ClassLoader)在Java运行环境中扮演着至关重要的角色。它负责将类的字节码加载到Java虚拟机(JVM)中,使得程序能够运行。ClassLoader是...
在Java编程中,静态代码块(Static Block)和类加载器(Class Loader)是两个重要的概念,它们在软件开发中有着广泛的应用。本案例聚焦于如何利用静态代码块结合类加载器来高效地获取资源文件,尤其是属性配置文件。...