java文件被编译为class文件,成为jvm机器码。jvm通过classloader将class的字节流加载,解析后变为class类。
-
Bootstrap ClassLoader/启动类加载器
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作。
-
Extension ClassLoader/扩展类加载器
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。
-
System ClassLoader/系统类加载器
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。
-
User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。
每个时刻,当前类有三种加载器可选择:
系统类加载器, 通过ClassLoader.getSystemClassLoader()
当前类加载器, 加载当前类的加载器。 Class.forName()会隐式调用当前类的加载器加载
当前线程类加载器, 通过Thread.getCurrentThread().getContextClassLoader()获取
加载classloader类的当前类所在的加载器,将会变成classloader的父加载器。
类加载采用双亲代理机制,加载类时,首先代理到父加载器,查找类的顺序变成从根加载器往叶子加载器向下寻找。好处是防止自定义包中实现String类。
每个加载器维护自身的名字空间,父加载器对子加载器可见,反之不可逆。jvm认定一个类,根据类名+加载器。
因为jdk中包含一些API接口类,这些类使用启动类加载器。而其接口实现类在第三方jar包中,采用系统加载类,会导致两边的类无法互相可见,最终导致ClassNotFound异常。解决方法是线程上下文加载器。
java动态载入class的两种方式:
1) implicit隐式,即利用实例化才载入的特性来动态载入class
2) explicit显式方式,又分两种方式:
java.lang.Class的forName()方法
java.lang.ClassLoader的loadClass()方法
static块在什么时候执行?
1)当调用forName(String)载入class时执行,如果调用ClassLoader.loadClass并不会执行.forName(String,false,ClassLoader)时也不会执行.
2)如果载入Class时没有执行static块则在第一次实例化时执行.比如new ,Class.newInstance()操作
3)static块仅执行一次
loadClass 为classloader主要方法,传入classname,中间做cache查找、双亲委派、安全控制之类的逻辑,最终返回Class
defineClass , 传入byte字节流,根据jvm的bytecode算法,将其解析为Class
========= tomcat classloader ===========
Bootstrap
|
System
|
Common
/ \
Webapp1 Webapp2 ...
bootstrap: jvm/lib/ext/*.jar
system: CLASSPATH/*.jar
common: tomcathome/lib/*.jar
webappx: webapp/root/WEB-INF/lib/*.jar webapp/root/WEB-INF/classes/
上图为tomcat加载器树状结构。于双亲委派策略不同的是,WebappClassLoader会优先加载本地的类,然后再委派双亲。(除了servlet api这样的系统类会滤过)
tomcat下线程默认上下文类加载器是 webapp class loader。
因此,应用app中,类的查找顺序是:
/WEB-INF/classes/
/WEB-INF/lib/*.jar
bootstrap
CLASSPATH
tomcathome/lib/
==================== example code =============
// invisible to parent classloader
// thread context classloader
// static block execute time
---------------------- result: -------------------
load class
class for name0
static
class for name1
~~~~~~ new A
Cons A
分享到:
相关推荐
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中。理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将...
Java ClassLoader是一个核心的Java运行时组件,负责加载类到Java虚拟机(JVM)中。它是Java平台的独特特性,因为它允许动态加载类,增强了软件的可扩展性和灵活性。这篇博文(虽然链接不可用)可能深入探讨了...
### Java ClassLoader原理详解 #### 摘要 本文探讨了Java虚拟机(JVM)中的一个重要特性:动态类加载(Dynamic Class Loading)。这一机制为Java平台提供了强大的能力,允许在运行时安装软件组件,例如从网络下载...
### Java ClassLoader与ClassPath详解 #### 一、概述 在Java编程中,类加载机制是十分关键的一个环节。类加载器(`ClassLoader`)负责将编译后的`.class`文件加载到Java虚拟机(JVM)中执行,而类路径(`ClassPath...
Java ClassLoader机制是Java虚拟机(JVM)中一个至关重要的组成部分,它的主要任务是将类的.class文件加载到JVM中,使得程序能够运行。ClassLoader不仅负责类的加载,还涉及类的验证、初始化等一系列过程。理解...
Java ClassLoader机制是Java运行时环境中的核心组件之一,它负责加载类到JVM(Java虚拟机)中,使得程序能够执行。理解ClassLoader的工作原理对于优化应用性能、处理类加载问题以及实现自定义加载器至关重要。 首先...
Java 类加载器(ClassLoader)是Java虚拟机(JVM)的重要组成部分,它负责在运行时查找并加载类到JVM中。这个教程将深入探讨ClassLoader的工作原理、类型以及如何自定义类加载器。 一、Java ClassLoader 基础 1. 类...
Java ClassLoader学习总结 Java 类加载机制是 Java 中一个非常重要的机制,它负责加载 Class 文件到 JVM,以供程序使用。ClassLoader 是 Java 中的一个抽象类,它的主要作用是加载 Class 文件到 JVM 中。...
### Java ClassLoader详解:以淘宝网为例 #### 一、ClassLoader概述 在Java环境中,类加载器(ClassLoader)是负责加载Java类到JVM的重要组件。它不仅实现了类的加载机制,还支持了动态加载与卸载的功能。本文将...
### Java ClassLoader理解详解 #### 一、引言 在商业流行的编程语言中,Java以其独特的运行机制脱颖而出:它在Java虚拟机(JVM)上运行。这意味着编译后的程序采用一种特殊的、与平台无关的格式,而不是针对特定...
Java 类加载器(ClassLoader)是Java虚拟机(JVM)中的一个重要组成部分,它负责加载类的字节码文件,使得程序能够运行。深入理解ClassLoader对于优化应用性能、处理类加载问题以及实现自定义加载策略至关重要。 一...
### Java ClassLoader (类加载器)详解 #### 一、教程提示 如果你正在查看这份文档,在线版中你可以点击下面的任何主题直接跳转到相应的部分。 1. **教程提示** 2. **介绍** 3. **类加载器结构** 4. **编译类加载...
破解java加密的ClassLoader.java,在classloader植入破解代码
Java ClassLoader是Java虚拟机(JVM)的重要组成部分,它负责加载类到JVM中运行。理解ClassLoader的工作原理对于深入学习Java以及进行JVM优化、插件开发等高级技术至关重要。下面将详细介绍Java ClassLoader的基本...
在深入探讨Java类加载器(ClassLoader)之前,我们首先需要了解它在Java运行时系统中的核心作用。类加载器是Java虚拟机(JVM)的一个关键组成部分,负责查找、加载和链接类文件到JVM中。它的存在使得Java应用程序...
Java ClassLoader 是一个重要的、但又常常被人忽略的 Java 运行时系统组件。它是负责在运行时查找和装入类文件的类。创建自己的 ClassLoader 可以以实用且有趣的方式定制 JVM,这样可以让您彻底重新定义如何将类文件...