JVM三种预定义类型类加载器:
启动(Bootstrap)类加载器:引导类装入器是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib 下面的类库加载到内存中,但是虚拟机出于安全等因素考虑,不会加载< Java_Runtime_Home >/lib存在的陌生类,开发者通过将要加载的非JDK自身的类放置到此目录下期待启动类加载器加载是不可能的。
标准扩展(Extension)类加载器:扩展类加载器是由 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader) 实现的。它负责将 < Java_Runtime_Home >/lib/ext 或者由系统变量 java.ext.dir 指定位置中的类库加载到内存中。
系统(System)类加载器:系统类加载器是由 Sun 的 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。AppClassLoader是加载Classpath中配置的类库.
类加载双亲委派机制:
JVM在加载类时默认采用的是双亲委派机制。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。关于虚拟机默认的双亲委派机制,
ClassLoader主要是通过loadClass()来加载类的。
loadClass()方法的代码:
// 首先判断该类型是否已经被加载
Class c = findLoadedClass(name);
if (c == null) {
//如果没有被加载,就委托给父类加载或者委派给启动类加载器加载
try {
if (parent != null) {
//如果存在父类加载器,就委派给父类加载器加载
c = parent.loadClass(name, false);
} else {
//如果不存在父类加载器,就检查是否是由启动类加载器加载的类,通过调用本地方法native Class findBootstrapClass(String name)
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
// 如果父类加载器和启动类加载器都不能完成加载任务,才调用自身的加载功能
c = findClass(name);
}
}
通过分析上面代码,可以得出类加载器的加载顺序:
BootstrapClassLoader-----ExtensionClassLoader----AppClassLoader---自定义的类加载器
怎么知道当前类使用了什么类加载器呢?
System.out.println(this.getClass().getClassLoader());----得到当前的类加载器
System.out.println(this.getClass().getClassLoader().getParent());----得到当前类的父加载器
System.out.println(this.getClass().getClassLoader().getParent().getParent());----得到当前类的父加载器的父加载器
假如当前类的加载器为sun.misc.Launcher$AppClassLoader@197d257,那么它的父加载器则为
sun.misc.Launcher$ExtClassLoader@7259da,但是扩展类加载器的父加载器则为NULL
扩展类加载器的父加载器为什么会为NULL呢?
由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。
扩展类加载器的父加载器怎么使父加载器为NULL的呢?
扩展类加载器(ExtClassLoader)调用ClassLoader(ClassLoader parent)构造函数将父类加载器设置为null
但是我们可以分析前面的代码。。当父加载器为NULL,JAVA会调用启动类加载器(findBootstrapClass0(name))
如何实现我们的自定义类加载器呢?
实现自定义加载器其它很简单。只要实现ClassLoader的findClass()方法就行了。
大概如下:
findClass(String name){
byte[] buffer=//读取文件的字节数组
return defineClass(buffer,0,buffer.length);
}
当自定义类加载器加载的类有继承相应的类或实现相应接口的话,必须把相应的父类或接口拷贝到同一路径。因为类加载器在加载子类时,会同时加载父类。
关于类的转型问题:
由于类加载器是相互隔离的,当classLoaderA加载了A类,classLoaderB也加载了A类。这个类对象是不能互相转型的。会报ClassCastException异常。
假如自定义类加载器加载A类时,而A类又实现了接口B时,我们是可以将A类的实例转成B接口的。原因是类加载器在加载A类时,会同时加载A类的所有父类(包括接口).
JAVA类加载器采用了委托模式。当一个类对象己经被加载了,就不会在去加载该类。还是直接返回。那么如何重新加载这个类呢?
实现自定义的类加载器,当类加载完成后。调用相应方法,然后在去掉相应类加载器的引用。这样类不会在存在类加载器中了。
比如:classLoaderA=null(去掉A加载器的引用)
分享到:
相关推荐
这篇博文“JAVA类加载器分析--热部署的缺陷”探讨了Java类加载机制以及在热部署场景下可能遇到的问题。热部署允许开发者在不重启应用的情况下更新代码,提高开发效率,但同时也存在一些挑战。 首先,我们来理解类...
通过阅读和分析该文件,你可以更直观地了解每个类加载器的角色及其交互方式。 总之,理解Java类加载器和Tomcat的类加载机制对于开发和调试基于Tomcat的应用程序至关重要。它涉及到类的查找、加载、初始化等过程,...
Java的类加载器是Java虚拟机(JVM)的核心组件之一,它负责将类的字节码文件从文件系统或网络中加载到JVM中,然后进行校验、解析和初始化,使得Java程序能够运行。类加载器的概念是Java动态加载和运行时类重定义的...
Java 类加载原理是Java运行时环境中的核心机制之一,它涉及到类的生命周期、类加载器的层次结构以及类的查找和加载过程。了解这一机制对于深入理解Java平台的工作原理至关重要,尤其是在开发自定义类加载器或者处理...
每个`Class`实例都关联着一个特定的类加载器,若加载器为`null`,则表示类由引导类加载器(bootstrap loader)加载,这是最基础的加载器,由JVM内置,非Java编写。 自定义类加载器(Custom ClassLoader)允许开发...
Java中的类加载器分为三个主要层次:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和系统类加载器(AppClassLoader)。启动类加载器负责加载JRE核心库,如`rt.jar`;扩展类加载器...
Java 类加载器是一个层次结构,包括启动类加载器、扩展类加载器和应用程序类加载器。每个类加载器都负责加载特定的类文件。Java 动态类加载机制通过委托模型来实现,委托模型是一种设计模式,用于实现类加载器之间的...
双亲委派模型是Java类加载器的重要特性之一,它的基本流程是:当一个类加载器收到加载类的请求时,它首先不会自己去尝试加载这个类,而是把请求委托给父类加载器去完成,每个层次的类加载器都是如此。如果父类加载器...
2. 再分析类加载 类加载的过程包括三个主要步骤:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)和初始化(Initialization)。其中,加载是查找并加载类的二进制数据;验证确保类...
类加载器在Tomcat中扮演着至关重要的角色,因为它们负责加载并管理运行时所需的Java类。这个"DevLoader.zip"文件可能包含与Tomcat自定义类加载器相关的资料,特别是名为"DevLoader"的类加载器,这可能是Tomcat为...
Java的类加载器分为Bootstrap ClassLoader(引导类加载器)、Extension ClassLoader(扩展类加载器)和App ClassLoader(应用程序类加载器)。自定义类加载器可以继承`java.lang.ClassLoader`,并覆盖`loadClass()`...
线程上下文类加载器(Thread Context ClassLoader)是Java提供的一种机制,允许线程在运行时指定一个类加载器,确保类由同一个类加载器加载。这对于应用程序服务器和插件系统尤其有用,因为它允许组件使用自己的类...
在Java编程语言中,类加载器(ClassLoader)是运行时环境的重要组成部分,它负责将类的字节码从各种来源(如硬盘、网络或内存)加载到Java虚拟机(JVM)中,使得程序能够执行。类加载工具则是辅助开发者理解和分析类...
Java加壳技术是一种保护Java程序不被轻易反编译或篡改的安全手段,它通过自定义类加载器来实现对原始字节码的包装。在Java中,类加载器是负责加载类到JVM(Java虚拟机)的核心组件。自定义类加载器允许开发者根据...
通过分析和学习这段代码,你可以更深入地理解类加载器的工作原理以及如何自定义类加载器来实现特定需求。 总之,“网络类加载器实现”是一种高级的Java技术,它结合了类加载机制和网络编程,使得Java应用程序具有更...
为了实现这个目标,需要对 Java 类加载器的体系结构、动态类加载机制原理、实现过程和实现方法进行分析。 Java 类加载器是 Java 虚拟机(JV M)的一部分,负责加载 Java 类文件并将其转换为可执行代码。 Java 类...
Java类加载器和类加载机制实例分析 Java类加载器和类加载机制是Java语言的核心机制之一,它们负责将.class文件加载到内存中,并生成对应的java.lang.Class对象。下面我们将从实例形式分析Java类加载器和类加载机制...
通过阅读《黑马程序员------类加载器学习注意点》这篇博文,以及对`classLoader.txt`文件的分析,我们可以更深入地掌握类加载器的相关知识,这对于解决实际问题和提升系统性能具有极大的帮助。在实践中不断探索和...
在Java中,每个类都由一个特定的类加载器来负责加载。当一个类加载器收到加载类的请求时,它不会立即加载,而是把这个任务委托给它的父类加载器去完成,直到到达顶层的启动类加载器(Bootstrap ClassLoader)。如果...