注:此为个人学习笔记,内容可能有些混乱,仅供参考。
1、
概览
因为类加载器 Java 类如同其它的 Java 类一样,也是要由类加载器来加载的。一般来说,开发人员编写的类加载器的父类加载器是系统类加载器。类加载器通过这种方式组织起来,形成树状结构。树的根节点就是引导类加载器。
2、
系统提供的类加载器
主要有下面三个:
·
引导类加载器
(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自
java.lang.ClassLoader
。
·
扩展类加载器
(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
·
系统类加载器
(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过
ClassLoader.getSystemClassLoader()
来获取它。
代码段:
package
xjt.classloader;
public
class
ClassLoaderTree {
public
static
void
main(String[] args) {
ClassLoader loader = ClassLoaderTree.
class
.getClassLoader();
/**
*
第一个输出的是
ClassLoaderTree类的类加载器,即系统类加载器。
*
它是
sun.misc.Launcher$AppClassLoader类的实例;
*
第二个输出的是扩展类加载器,是
*
sun.misc.Launcher$ExtClassLoader类的实例。
*
需要注意的是这里并没有输出引导类加载器,
*
这是由于有些
JDK
的实现对于
父类加载器是引导类加载器的情况,
* getParent()方法返回
null
。
*
*/
while
(loader !=
null
) {
System.
out
.println(loader.toString());
loader = loader.getParent();
}
}
}
3、
类加载器的代理模式
类加载器在尝试自己去查找某个类的字节代码并定义它时,
会先代理给其父类加载器,由父类加载器先去尝试加载这个类
,依次类推。在介绍代理模式 背后的动机之前,首先需要说明一下 Java 虚拟机是
如何判定两个 Java 类是相同的
。Java 虚拟机不仅要看类的
全名是否相同
,还要看加载此类的
类加载器是否一样
。只有两者都相同的情况,才认为两个类是相同的。
4、
加载类的过程
真正完成类的加载工作是通过调用
defineClass
来实现的;而启动类的加载过程是通过调用
loadClass
来实现的。
方法
loadClass()
抛出的是
java.lang.ClassNotFoundException
异常;
方法
defineClass()
抛出的是
java.lang.NoClassDefFoundError
异常。
遇到
ClassNotFoundException
和
NoClassDefFoundError
等异常的时候,应该检查抛出异常的类的类加载器和当前线程的上下文类加载器
。
5、
Class.forName
Class.forNameClass.forName
的一个很常见的用法是在加载数据库驱动的时候。如
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance()
用来加载 Apache Derby 数据库的驱动。是一个静态方法,同样可以用来加载类。
6、
类加载器与 Web
容器
对于运行在 Java EE™容器中的 Web 应用来说,类加载器的实现方式与一般的 Java 应用
有所不同
。不同的 Web 容器的实现方式也会有所不同。以 Apache Tomcat 来说,
每个 Web 应用都有一个对应的类加载器实例
。该类加载器也使用代理模式,所不同的是它是
首先尝试去加载某个类
,如果找不到再代理给父类加载器。这与一般类加载器的顺 序是相反的。这是 Java Servlet 规范中的推荐做法,其目的是使得
Web 应用自己的类的优先级高于 Web 容器提供的类
。这种代理模式的一个例外是:
Java 核心库的类是不在查找范围之内
的。这也是为了保证 Java 核心库的类型安全。
7、
OSGi
(Open Service Gateway Initiative
)
是 Java 上的动态模块系统。
OSGi 中的每个模块(bundle)都包含 Java 包和类。模块可以声明它所依赖的需要导入(import)的其它模块的 Java 包和类(通过
Import-Package
),也可以声明导出(export)自己的包和类,供其它模块使用(通过
Export-Package
)。也就是说需要能够隐藏和共享一个模块中的某些 Java 包和类。这是通过 OSGi 特有的类加载器机制来实现的。
OSGi 中的每个模块都有对应的一个类加载器。
分享到:
相关推荐
类加载器在Java中扮演着至关重要的角色,不仅负责加载类,还维护了类的层次关系,确保了系统的稳定性和安全性。通过理解和掌握类加载器的工作原理及其不同类型的加载器,可以帮助开发者更好地管理Java应用程序的依赖...
类加载器是Java运行时环境的重要组成部分,负责加载类到JVM中,并确保类的正确加载与隔离。类加载器的基本结构如下: 1. **引导类加载器**(Bootstrap Class Loader):这是系统默认的类加载器,负责加载JRE/lib/rt...
类加载器的作用不仅仅是加载类,还包括确保类的唯一性,避免重复加载,并且遵循特定的加载顺序。以下是对类加载器原理的详细解释: 1. 类加载器作用: 当JVM启动时,如果需要使用某个类,对应的类加载器会将这个类...
总结起来,Java 类加载器加密是一种增强程序安全性的技术,通过自定义类加载器和解密逻辑,可以在加载类之前对其进行加密,提高代码的保护性。同时,结合反射机制,即使类是加密状态,也能正常执行程序。这种技术常...
- 使用`Class.forName(String className)`或`Class.forName(String className, boolean initialize, ClassLoader loader)`方法显式加载类。 - 使用`ClassLoader.loadClass(String name)`方法显式加载类。 其中,`...
Java中的类加载器遵循一个原则叫做“父母委托模型”,即当一个类加载器收到类加载请求时,首先将加载任务委托给父类加载器,只有当父类加载器无法完成加载时才会尝试自己加载。 这种设计模式的好处在于避免了类的...
Java类加载器是Java虚拟机(JVM)的关键组成部分,它负责查找并加载类到内存中,使得程序能够运行。自定义Java类加载器允许我们根据特定需求扩展默认的加载机制,例如,从非标准位置加载类或者实现动态加载。在Java...
java类加载器学习三、类加载器的委托模式
除了这三种预定义的类加载器,Java还提供了一种特殊的**线程上下文类加载器(Thread Context ClassLoader)**,它允许在特定线程中加载类时使用非默认的类加载器。这在插件框架和OSGi等动态部署环境中尤其有用。 ...
每个类加载器在尝试加载类时,会先委托给父类加载器,只有当父类加载器无法加载时,才会尝试自己加载。这种机制保证了Java的核心类库只被加载一次,同时也确保了类的唯一性。 Tomcat的类加载器工作流程可以总结为:...
类加载的过程遵循“双亲委派模型”(Delegation Model),即当一个类加载器接收到加载类的请求时,它首先会委托其父加载器尝试加载,只有在父加载器无法加载时,自身才会尝试加载。这样设计可以避免类的重复加载,并...
当一个类加载器尝试加载类时,它会先委托给父类加载器,只有在父类加载器无法找到相应类时,子类加载器才会尝试加载。这种机制避免了类的重复加载,并且允许自定义类加载器覆盖父类加载器的行为。 线程上下文类加载...
双亲委派模型是Java类加载器的重要特性之一,它的基本流程是:当一个类加载器收到加载类的请求时,它首先不会自己去尝试加载这个类,而是把请求委托给父类加载器去完成,每个层次的类加载器都是如此。如果父类加载器...
例如,如果你正在开发一个需要从远程服务器获取辅助代码的系统,你可以创建一个类加载器,它可以从指定的URL加载类字节码,然后将其转换为java.lang.Class对象。这样做可以让应用程序动态地更新和使用远程服务器上的...
4. **自定义类加载器(Custom Class Loader)**:开发者可以根据需要创建自定义的类加载器,以便支持特殊的需求,比如从网络加载类或动态地修改字节码。 #### 五、类加载过程 类加载过程主要包括三个阶段:加载、...
Java 类加载器是 Java 运行时环境中不可或缺的组成部分,负责将 .class 文件加载到 JVM 中。理解类加载器的工作原理对于深入掌握 Java 语言及其运行机制至关重要。本文将详细探讨 Java 类加载器的概念、类型以及工作...
该文件是JVM中关于类加载机制的知识整理的思维导图,包括类加载机制概述、类加载的生命周期、加载时机、加载过程、类加载、类的初始化和实例化等几个大方面进行了讲解,其中类加载中还对JVM三种预定义类加载器进行了...
为了避免重复加载类和防止核心类库被篡改,Java采用了委派模式来加载类。即如果一个类加载器收到了类加载的请求,它首先不会自己尝试去加载这个类,而是将加载请求委托给父类加载器去完成,每一层都是如此,只有当...