ClassLoader详解
- 格式:doc
- 大小:190.00 KB
- 文档页数:34
ClassLoader.getResourceAsStream(name) 是 Java 中用于从类加载器的类路径上获取资源文件流的方法。
这个方法在读取配置文件、图像、音频等资源时非常有用。
以下是关于该方法工作原理的详细解析:1. 类加载器(ClassLoader)Java 使用类加载器来动态加载 Java 类。
类加载器负责从文件系统、网络或其他来源读取类的字节码,并将其转换为 JVM 可以理解的格式。
Java 中的每个类都是由某个类加载器加载的。
类加载器之间存在父子关系,形成一个树状结构。
通常,每个 Java 应用至少有三个类加载器:引导类加载器(Bootstrap ClassLoader):加载 JDK 中的核心类库,如 ng.* 等。
它不是由 Java 实现的,而是由 JVM 的原生代码实现的。
扩展类加载器(Extension ClassLoader):加载 JDK 的扩展目录(通常是 lib/ext 目录或 JAVA_HOME/jre/lib/ext)中的 JAR 包和类文件。
系统类加载器(System ClassLoader):加载 CLASSPATH 环境变量中指定的类库,它是应用程序默认的类加载器。
2. getResourceAsStream(name) 方法getResourceAsStream(name) 方法用于从类加载器的类路径中查找并返回一个资源的输入流。
资源的名称是相对于类路径的。
资源查找:当调用 getResourceAsStream(name) 方法时,类加载器会按照特定的算法在类路径中查找资源。
它通常首先检查父类加载器是否有该资源,如果没有,再检查自己的资源。
资源名称:资源的名称是相对于“包”的。
例如,如果有一个名为 com.example.MyClass 的类,并且它位于一个名为 MyClass.class 的文件中,那么与该类在同一个目录下的名为config.properties 的文件的资源名称就是 com/example/config.properties。
classloader 机制(最新版)目录1.类加载器(ClassLoader)机制概述2.类加载器的作用3.类加载器的类型4.类加载器的加载过程5.类加载器的优缺点正文一、类加载器(ClassLoader)机制概述类加载器(ClassLoader)机制是 Java 运行时系统中的一个核心组件,负责将磁盘上的字节码文件 (.class 文件) 加载到内存中并生成对应的 Java 类。
类加载器是 Java 类加载和链接的关键部分,它负责将字节码文件读取到内存中,并为类创建静态结构。
二、类加载器的作用类加载器的主要作用是将字节码文件加载到内存中,生成 Java 类的内部表示形式,主要包括以下三个步骤:1.加载:类加载器将字节码文件读取到内存中,生成一个字节数组。
2.链接:类加载器将字节数组中的数据转换成 Java 类的内部表示形式,主要包括验证、准备和解析三个过程。
3.初始化:类加载器为类分配内存,并执行类的静态初始化代码。
三、类加载器的类型Java 中有多种类型的类加载器,主要有以下几种:1.Bootstrap Class Loader:启动类加载器,负责加载 Java 的核心类库,如 ng 包。
2.Extension Class Loader:扩展类加载器,负责加载 Java 的扩展库,如javax.swing 包。
3.System Class Loader:系统类加载器,负责加载 Java 的应用类库和用户自定义类。
er Class Loader:用户类加载器,允许用户自定义类加载器,可以自定义类的加载行为。
四、类加载器的加载过程类加载器的加载过程主要包括以下三个步骤:1.加载:类加载器将字节码文件读取到内存中,生成一个字节数组。
2.链接:类加载器将字节数组中的数据转换成 Java 类的内部表示形式,主要包括验证、准备和解析三个过程。
3.初始化:类加载器为类分配内存,并执行类的静态初始化代码。
classloader 范围Classloader(类加载器)是Java虚拟机(JVM)的一个重要组成部分,它负责将Java类加载到内存中,以供程序使用。
Classloader的范围是指它在加载类时所涵盖的范围,即它能够加载的类的位置和来源。
在Java中,ClassLoader可以分为三个范围:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。
1. 引导类加载器(Bootstrap ClassLoader):引导类加载器是JVM自身的一部分,它负责加载Java虚拟机自身需要的基础类,如ng包下的类。
引导类加载器是无法被Java代码直接调用或访问的,它是用C++实现的,并由JVM实例初始化。
2. 扩展类加载器(Extension ClassLoader):扩展类加载器用于加载Java的扩展库,它主要负责加载Java平台扩展目录(Java Home/jre/lib/ext)下的JAR文件。
扩展类加载器是由uncher$ExtClassLoader实现的,并由Java标准扩展机制提供。
3. 应用程序类加载器(Application ClassLoader):应用程序类加载器是最常用的类加载器,在Java应用程序中被广泛使用。
它负责加载程序的classpath中的类,包括应用程序自身的类和第三方库的类。
这个类加载器是通过uncher$AppClassLoader实现的。
类加载器的范围决定了类的加载顺序和加载位置。
当一个类被加载时,会首先由引导类加载器进行加载。
如果引导类加载器无法加载该类,会将该请求传递给扩展类加载器。
如果扩展类加载器仍然无法加载,最后轮到应用程序类加载器进行加载。
如果所有的类加载器均无法加载该类,将抛出ClassNotFoundException异常。
classloader的原理,举出应用场景及工作实例ClassLoader的原理ClassLoader(类加载器)是Java虚拟机的一个重要组成部分,它负责将Java字节码文件加载到内存中,并生成对应的Java类。
ClassLoader的原理涉及到Java虚拟机的类加载机制,下面将详细介绍ClassLoader的原理、应用场景和工作实例。
ClassLoader的原理主要包括以下几个方面:1. 类加载的过程类加载是指将类的字节码文件加载到内存中,并生成对应的Java类。
类的加载过程可以分为以下几个步骤:(1)加载:通过类的全限定名(例如com.example.MyClass)在文件系统或网络中查找对应的字节码文件,找到后将其读取到内存中。
(2)连接:连接是指将已经加载的类与其他的类、接口或者静态变量进行关联。
连接包括验证、准备和解析三个阶段。
- 验证:验证阶段主要是对字节码文件进行校验,确保其符合Java虚拟机的规范。
- 准备:准备阶段主要是为类的静态变量分配内存,并设置默认值。
- 解析:解析阶段主要是将类、接口或者静态变量与实际内存地址进行关联。
(3)初始化:初始化阶段是类加载的最后一个阶段,主要是执行类的静态代码块和静态变量的初始化。
2. 类加载器的分类Java虚拟机中存在多个不同类型的类加载器,主要分为以下几种:(1)引导类加载器(Bootstrap ClassLoader):负责加载Java 核心类库,它是Java虚拟机自身内嵌的一部分,不同的Java虚拟机实现可能不同。
(2)扩展类加载器(Extension ClassLoader):负责加载Java 扩展类库,一般对应于Java虚拟机的jre/lib/ext目录或java.ext.dirs 系统属性指定的路径。
(3)应用程序类加载器(Application ClassLoader):负责加载应用程序的类,一般对应于CLASSPATH 环境变量指定的路径或者用户自定义的路径。
ClassLoader详解(JDK9以前)1.概述Java虚拟机把描述类的数据从Class⽂件加载到内存, 并对数据进⾏校验、转换解析和初始化, 最终形成可以被虚拟机直接使⽤的Java类型,这个过程被称作虚拟机的类加载机制。
与那些在编译时需要进⾏连接的语⾔不同,在Java语⾔⾥⾯,类型的加载、连接和初始化过程都是在程序运⾏期间完成的,这种策略让Java语⾔进⾏提前编译会⾯临额外的困难,也会让类加载时稍微增加⼀些性能开销,但是却为Java应⽤提供了极⾼的扩展性和灵活性, Java天⽣可以动态扩展的语⾔特性就是依赖运⾏期动态加载和动态连接这个特点实现的。
例如,编写⼀个⾯向接⼝的应⽤程序,可以等到运⾏时再指定其实际的实现类,⽤户可以通过Java预置的或⾃定义类加载器,让某个本地的应⽤程序在运⾏时从⽹络或其他地⽅上加载⼀个⼆进制流作为其程序代码的⼀部分。
这种动态组装应⽤的⽅式⽬前已⼴泛应⽤于Java程序之中,从最基础的Applet、JSP到相对复杂的OSGi技术,都依赖着Java语⾔运⾏期类加载才得以诞⽣。
简⾔之, 它是⽤来加载 Class 的。
它负责将 Class 的字节码形式转换成内存形式的 Class 对象。
字节码可以来⾃于磁盘⽂件 *.class,也可以是 jar 包⾥的 *.class,也可以来⾃远程服务器提供的字节流,字节码的本质就是⼀个字节数组 []byte,它有特定的复杂的内部格式。
JVM 运⾏实例中会存在多个 ClassLoader,不同的 ClassLoader 会从不同的地⽅加载字节码⽂件。
它可以从不同的⽂件⽬录加载,也可以从不同的 jar ⽂件中加载,也可以从⽹络上不同的静态⽂件服务器来下载字节码再加载。
1.1 基础知识1.⼀个JVM实例(Java应⽤程序)⾥⾯的所有类都是通过ClassLoader加载的。
2.不同的ClassLoader在JVM中有不同的命名空间,⼀个类实例(Class)的唯⼀标识是: 【全类名 + ClassLoader】也就是不同的ClassLoader加载同⼀个类⽂件,也会得到不相同的Class实例。
classloader机制-回复问题:什么是classloader机制?回答:Classloader(类加载器)是Java虚拟机(JVM)的一个重要组成部分,它负责从文件系统、网络或其他来源加载Java类文件并创建对应的类对象。
Classloader机制是Java应用程序在运行时加载类的过程,它在Java 开发中起着至关重要的作用。
Classloader机制的核心任务是根据类的全限定名(fully qualified name)找到对应的字节码,并将其转化为一个可用的类对象。
Classloader 实现了类的动态加载,它使得Java应用程序可以在运行时根据需要加载特定的类。
Classloader机制的工作方式如下:1. 双亲委派模型:Classloader按照一定的层次结构进行组织,每个Classloader都有一个父ClassLoader,Java虚拟机中的所有Classloader 构成了一个树状结构。
当一个类需要被加载时,ClassLoader会首先委托其父ClassLoader去尝试加载。
只有当父ClassLoader无法加载该类时,ClassLoader才会尝试自己加载。
2. 加载过程:ClassLoader接收到类的全限定名后,首先检查该类是否已经被加载,如果已经被加载,直接返回已加载的类对象。
如果没有被加载,则ClassLoader会利用自身的加载逻辑,根据类的全限定名找到对应的字节码并加载,将其转化为一个可用的类对象。
3. 类加载器的关系:ClassLoader是Java应用程序的一个重要组件,不同的ClassLoader之间有一定的关系。
通常情况下,一个Web应用程序拥有自己的类加载器,它可以加载位于WEB-INF/classes目录或WEB-INF/lib文件夹中的类。
另外,JVM也提供了一些预定义的ClassLoader,如Bootstrap Classloader(引导类加载器)、Extension Classloader(扩展类加载器)和System Classloader(系统类加载器),它们有各自的加载策略和加载范围。
classloader加载原理classloader是java中一个比较重要的类加载器,每一个程序和类都会存在一个classloader,classloader有三种主要的工作:加载类的二进制字节流、连接、初始化。
一、Classloader加载机制1、首先classloader会按照特定的方式去搜索类文件,当它找到了相应的类文件之后,它会将这个类文件转换成为二进制字节流,这里涉及到编译程序,classloader会使用编译程序将源程序编译成可执行文件。
2、接下来classloader会将这些二进制字节流存储在内存中,然后classloader会连接这些字节流,这一步是它将这些字节流组装成一个完整的类文件,这里涉及到类的加载,这些加载的类可以被访问,但是它们的代码还未被执行。
3、最后classloader会初始化这些加载的类,这一步就是它将这些类的代码执行,这里classloader会执行所有类变量的初始化,同时也会执行所有静态代码块的内容,最后我们就可以得到一个完整的类文件。
二、Classloader的三种类型1、Bootstrap Classloader:它是用来加载JRE的核心类的,它的实现是C++语言,它的加载范围是从<JAVA_HOME>lib下面开始,这个类加载器不需要程序员编写任何外部类。
2、Extension Classloader:它是用来加载扩展类的,从<JAVA_HOME>libext开始加载,它继承自Bootstrap Classloader,这种类加载器也不需要程序员手动编写任何外部类。
3、Application Classloader:它是用来加载程序类的,它继承自Extension Classloader,它从ClassPath(来自系统变量或者命令行参数)所指定的路径中加载类,但是它不会加载扩展类。
三、Classloader安全机制1、安全性验证:Classloader在加载类的时候会先验证这个类文件,检查它是否符合class文件格式,其次classloader会过滤掉由它本身加载的不安全的类,这涉及到安全管理器的配置,例如:可以设置它只能加载特定的域名下的类文件。
ClassLoader是Java中的类加载器,它的主要工作是将Class加载到JVM中。
以下是其运行机制:
1. 父优先加载机制:ClassLoader采用了一种“父优先”的等级加载机制,也就是说,当一个类需要被加载时,ClassLoader会首先检查它的父类是否已经被加载。
如果父类已经被加载,那么就直接使用父类的类对象;如果父类还没有被加载,那么就先加载父类,然后再加载当前类。
这种机制也适用于同一加载器中加载的类之间的依赖关系。
2. 类加载过程:当一个类需要被加载时,ClassLoader会首先找到这个类的class文件,并把这个文件包含的字节码加载进内存。
然后,它会对这些字节码进行解析和初始化。
在解析过程中,ClassLoader 会将类字节码重新解析成JVM统一要求的对象格式,并生成类的Class对象。
3. 显示和隐式加载:ClassLoader有两种加载方式:显示加载和隐式加载。
隐式加载是指不需要代码调用类加载器加载需要的类,而是通过JVM自动加载。
显示加载则需要调用类加载器来加载类。
比如,使用类Class中的forName()方法、ClassLoader中的loadClass()方法或findSystemClass()方法等来加载类。
总的来说,ClassLoader在Java中扮演着非常重要的角色,它负责将Class加载到JVM中,并审查每个类应该由谁来加载,以及将类字节码重新解析成JVM统一的对象格式。
classloadergetresource方法详解在Java语言中,ClassLoader类是一个重要的类,它在Java虚拟机中用来加载Java类文件或者其他相关资源文件。
相信很多Java开发者都会用到ClassLoader类的getResource()方法来获取资源文件,那么今天我们就来详细讲解一下ClassLoader中的getResource()方法。
一、ClassLoader定义ClassLoader是一个作用在Java虚拟机的类,它用来加载类文件或者其他的资源文件。
Java虚拟机通过该类的实例,通过调用ClassLoader中的findClass()方法,加载指定包名称的类文件到虚拟机运行环境中,从而形成Java代码执行的最后环节。
二、getResource()介绍getResource()是ng.ClassLoader中的一个基础函数,它用于在指定的class loader的classpath中搜索得到指定name的资源。
getResource()方法可以用URL对象的形式返回位于给定名称的文件和文件夹的资源。
它在类路径中查找一个具有给定名称的资源,并且返回的是资源的URL对象。
由于该方法是父类加载器的方法,加载资源时会自动委托给其父类加载器。
当找不到资源时返回的将是null值。
三、getResource()与getResourceAsStream()方法区别但是,有些Java开发者会有疑问,在获取资源时,是使用getResource()好还是使用getResourceAsStream()方法更好呢?其实,这两者之间的区别是非常细微的,主要有两个方面:首先是返回值,getResource()方法返回一个URL对象,表示类加载器可以在给定的路径上找到的资源,而getResourceAsStream()方法返回一个输入流对象,表示类加载器可以在给定的路径上找到的资源的数据。
另外,getResourceAsStream()方法中的路径名必须以“/”开头,不然将会找不到指定文件。
ng 类ClassLoader ng.Object ng.ClassLoader直接已知子类:SecureClassLoaderpublic abstract class ClassLoader extends Object类加载器是负责加载类的对象。
ClassLoader 类是一个抽象类。
如果给定类的二进制名称,那么类加载器会试图查找或生成构成类定义的数据。
一般策略是将名称转换为某个文件名,然后从文件系统读取该名称的“类文件”。
每个Class 对象都包含一个对定义它的ClassLoader 的引用。
数组类的Class 对象不是由类加载器创建的,而是由Java 运行时根据需要自动创建。
数组类的类加载器由Class.getClassLoader() 返回,该加载器与其元素类型的类加载器是相同的;如果该元素类型是基本类型,则该数组类没有类加载器。
应用程序需要实现ClassLoader 的子类,以扩展Java 虚拟机动态加载类的方式。
类加载器通常由安全管理器使用,用于指示安全域。
ClassLoader 类使用委托模型来搜索类和资源。
每个ClassLoader 实例都有一个相关的父类加载器。
需要查找类或资源时,ClassLoader 实例会在试图亲自查找类或资源之前,将搜索类或资源的任务委托给其父类加载器。
虚拟机的内置类加载器(称为"bootstrap class loader")本身没有父类加载器,但是可以将它用作ClassLoader 实例的父类加载器。
通常情况下,Java 虚拟机以与平台有关的方式,从本地文件系统中加载类。
例如,在UNIX 系统中,虚拟机从CLASSPA TH 环境变量定义的目录中加载类。
然而,有些类可能并非源自一个文件;它们可能源自其他来源(如网络),也可能是由应用程序构造的。
defineClass 方法将一个byte 数组转换为Class 类的实例。
这种新定义的类的实例可以使用Class.newInstance 来创建。
类加载器ClassLoader源码解析1、ClassLoader作⽤类加载流程的"加载"阶段是由类加载器完成的。
2、类加载器结构结构:BootstrapClassLoader(祖⽗)-->ExtClassLoader(爷爷)-->AppClassLoader(也称为SystemClassLoader)(爸爸)-->⾃定义类加载器(⼉⼦)关系:看括号中的排位;彼此相邻的两个为⽗⼦关系,前为⽗,后为⼦2.1、BootstrapClassLoader下边简称为bootC++编写为ExtClassLoader的⽗类,但是通过ExtClassLoader的getParent()获取到的是null(在类加载器部分:null就是指boot)主要加载:E:\Java\jdk1.6\jre\lib\*.jar(最重要的就是:rt.jar)2.2、ExtClassLoader:下边简称为extjava编写,位于sun.misc包下,该包在你导⼊源代码的时候是没有的,需要重新去下主要加载:E:\Java\jdk1.6\jre\lib\ext\*.jar(eg.dnsns.jar)2.3、AppClassLoader:下边简称为appjava编写,位于sun.misc包下主要加载:类路径下的jar2.4、⾃定义类加载器:下边简称为custom⾃⼰编写的类加载器,需要继承ClassLoader类或URLClassLoader,并⾄少重写其中的findClass(String name)⽅法,若想打破双亲委托机制,需要重写loadClass⽅法主要加载:⾃⼰指定路径的class⽂件3、全盘负责机制概念:假设ClassLoaderA要加载class B,但是B引⽤了class C,那么ClassLoaderA先要加载C,再加载B,"全盘"的意思就是,加载B的类加载器A,也会加载B所引⽤的类4、双亲委托机制这也是类加载器加载⼀个类的整个过程。
jvm 参数打印classloader 顺序-概述说明以及解释1.引言1.1 概述JVM(Java Virtual Machine)是一个虚拟机,是Java程序运行的环境。
JVM参数是用来设置虚拟机运行时的参数,在优化性能和调试问题时起着重要作用。
在Java应用程序运行时,JVM会根据这些参数的设置来进行内存管理、垃圾回收、类加载等操作。
本文将重点讨论JVM参数对classloader加载顺序的影响。
Classloader是在Java虚拟机中用来加载类文件的关键组件,它会根据设定的参数来确定类文件加载的顺序,这对于应用程序的性能和稳定性具有重要影响。
在接下来的章节中,我们将详细介绍JVM参数的概念和作用,分类以及设置方式,探讨JVM参数在classloader加载顺序中的作用,并展望未来JVM参数优化的方向。
通过本文的阐述,读者可以更深入地了解JVM 参数对classloader的影响,从而优化应用程序的性能和稳定性。
json{"1.2文章结构":{"本文将首先介绍JVM参数的概念和作用,以帮助读者更好地理解JVM参数的重要性。
接着,将对JVM参数进行分类,让读者了解不同类型的JVM参数所起的作用。
然后,将详细介绍JVM参数的设置方式,以帮助读者正确地配置JVM参数。
在结论部分,将总结JVM参数对classloader的影响,并重点强调classloader的加载顺序,最后展望未来JVM参数优化的方向。
通过本文,读者将深入了解JVM参数与classloader 之间的关系,为优化应用程序性能提供指导。
"}1.3 目的本文旨在探讨JVM参数对classloader加载顺序的影响。
通过分析不同类型的JVM参数以及它们的设置方式,我们将深入了解在实际应用中如何调整参数来优化classloader的加载顺序。
通过本文的讨论,读者将能够更好地理解JVM参数的作用,为优化应用程序性能提供有力的参考依据。
Java类加载器—classloader的原理及应⽤引⾔classloader顾名思义,即是类加载。
虚拟机把描述类的数据从class字节码⽂件加载到内存,并对数据进⾏检验、转换解析和初始化,最终形成可以被虚拟机直接使⽤的Java类型,这就是虚拟机的类加载机制。
了解java的类加载机制,可以快速解决运⾏时的各种加载问题并快速定位其背后的本质原因,也是解决疑难杂症的利器。
因此学好类加载原理也⾄关重要。
⼀、classloader的加载过程类从被加载到虚拟机内存到被卸载,整个完整的⽣命周期包括:类加载、验证、准备、解析、初始化、使⽤和卸载七个阶段。
其中验证,准备,解析三个部分统称为连接。
接下来我们可以详细了解下类加载的各个过程。
classloader的整个加载过程还是⾮常复杂的,具体的细节可以参考《深⼊理解java虚拟机》进⾏深⼊了解。
为了⽅便记忆,我们可以使⽤⼀句话来表达其加载的整个过程,“家宴准备了西式菜”,即家(加载)宴(验证)准备(准备)了西(解析)式(初始化)菜。
保证你以后能够很快的想起来。
虽然classloader的加载过程有复杂的5步,但事实上除了加载之外的四步,其它都是由JVM虚拟机控制的,我们除了适应它的规范进⾏开发外,能够⼲预的空间并不多。
⽽加载则是我们控制classloader实现特殊⽬的最重要的⼿段了。
也是接下来我们介绍的重点了。
⼆、 classloader双亲委托机制classloader的双亲委托机制是指多个类加载器之间存在⽗⼦关系的时候,某个class类具体由哪个加载器进⾏加载的问题。
其具体的过程表现为:当⼀个类加载的过程中,它⾸先不会去加载,⽽是委托给⾃⼰的⽗类去加载,⽗类⼜委托给⾃⼰的⽗类。
因此所有的类加载都会委托给顶层的⽗类,即Bootstrap Classloader进⾏加载,然后⽗类⾃⼰⽆法完成这个加载请求,⼦加载器才会尝试⾃⼰去加载。
使⽤双亲委派模型,Java类随着它的加载器⼀起具备了⼀种带有优先级的层次关系,通过这种层次模型,可以避免类的重复加载,也可以避免核⼼类被不同的类加载器加载到内存中造成冲突和混乱,从⽽保证了Java核⼼库的安全。
classloader机制-回复什么是ClassLoader机制?ClassLoader 机制是Java 虚拟机(JVM)的一项关键功能,用于动态加载Java 类和资源文件。
类加载器负责将字节码文件加载到内存中,并生成对应的Class 对象,使得程序能够使用这些类和资源。
ClassLoader 机制是Java 实现动态性的重要手段之一,它使得Java 程序在运行时能够根据需要动态加载和使用类,而不需要在编译时事先确定全部的类。
Class类层次结构Class 类是Java 反射机制的核心,它代表着Java 程序的类和接口。
ClassLoader 通过加载字节码文件生成对应的Class 对象,从而在程序运行期间获取和使用类的信息。
Class 类的层次结构如下所示:;位置不同,要想了解其中的原因需要从类的使用时JVM完成的动作说起,在一个类被JVM使用时大致经历如下三步(加载—链接—初始化)那么一个类被JVM使用时,必须预先经历如上图所述的加载过程。
那么什么样的条件才会触发上述过程的执行呢?JAVA程序使用类分为主动使用和被动使用,在JVM的实现规范中要求,所有类的“主动使用“虚拟机才执行上述过程初始化相应的类,那么问题就归结为“主动使用”的意义。
1.创建类的实例。
Object A = new ClassA();2.访问某个类或接口的静态变量或对静态变量赋值。
如Class A{static a} 访问A.a时。
需要指出的是访问类的static final int x = 0(编译时常量)并不被认为是类的主动使用,同样的假如有条件Class A extends B;B{static a}如果使用A.a时只会初始化类B,这种情况被认为是对父类的主动使用。
3.调用类的静态方法4.使用反射机制(Class.ForName(xxx)),而ClassLoader.load(并不会初始化类)5.初始化一个类的子类时,父类也被主动使用6.启动类(java TestMain)下面文章将针对上述过程给出比较详细的说明。
加载过程总的来说类的加载是JVM使用类加载器(如系统类加载器、扩展加载器、根加载器)在特定的加载路径里寻找class文件,并将class文件中的二进制数据读入到内存中,其中class 的数据结构被放置在运行时数据区的方法区类,并且在堆区里创建该类的Class对象,用来封装类的数据结构信息。
classloader的使用ClassLoader是Java虚拟机(JVM)的一个重要组件,负责加载Java类文件到内存中,并生成对应的Class对象。
它主要有以下几种使用方式:1. 系统类加载器(System ClassLoader):也称为应用类加载器,负责加载Java应用程序的相关类。
可以通过Thread.currentThread().getContextClassLoader()方法获取当前线程的类加载器。
2. 扩展类加载器(Extension ClassLoader):负责加载Java的扩展类库(位于%JRE_HOME%/lib/ext目录下)。
扩展类加载器是系统类加载器的父加载器。
3. 引导类加载器(Bootstrap ClassLoader):也称为根类加载器,负责加载JVM自身的类。
它是Java虚拟机实现的一部分,一般无法直接获取到引导类加载器的引用。
4. 自定义类加载器:ClassLoader提供了一些扩展点,可以自定义类加载器来实现特定的类加载行为。
通过继承ClassLoader类,重写findClass()方法,可以实现自定义的类加载逻辑。
使用ClassLoader加载类的步骤如下:1. 创建ClassLoader对象:可以使用系统类加载器或自定义的类加载器。
2. 调用ClassLoader的loadClass()方法:传入类的全限定名,返回一个Class对象。
3. 使用获取到的Class对象进行相关操作:如实例化对象、调用方法等。
注意事项:- ClassLoader只负责加载类文件,对于类的初始化操作需要在使用时进行。
- 在多个ClassLoader中加载同一个类,可能会导致类的不一致。
因此,通常建议使用同一个ClassLoader加载相关的类。
- ClassLoader的双亲委派模型会根据不同的类加载器的继承关系,按照从上到下的顺序查找类文件。
java classloader工作机制Java ClassLoader是Java虚拟机(JVM)的一个重要组成部分,它负责将Java类加载到JVM中。
在Java中,类是以.class文件的形式存在的,而ClassLoader就是将这些.class文件加载到JVM中的工具。
Java ClassLoader的工作机制可以分为三个步骤:加载、链接和初始化。
1. 加载ClassLoader的第一个任务是加载类。
当Java程序需要使用某个类时,ClassLoader会在类路径中查找该类的.class文件,并将其加载到JVM中。
类路径可以由多个路径组成,包括系统类库、用户自定义类库等。
ClassLoader会根据类的全限定名(包括包名和类名)来查找对应的.class文件。
如果找到了该文件,ClassLoader会将其读入内存,并生成一个对应的Class对象。
这个Class对象包含了该类的所有信息,包括类名、父类、接口、方法、字段等。
2. 链接ClassLoader加载类后,还需要进行链接。
链接分为三个步骤:验证、准备和解析。
验证:ClassLoader会对类进行验证,确保其符合Java语言规范和JVM规范。
验证的内容包括语法检查、语义检查、字节码验证等。
准备:ClassLoader会为类的静态变量分配内存,并设置默认值。
这些静态变量在类加载时就已经存在,而不是在类实例化时才创建。
解析:ClassLoader会将类中的符号引用解析为直接引用。
符号引用是指在类中使用的其他类、方法、字段等的引用,而直接引用是指实际的内存地址。
3. 初始化ClassLoader完成链接后,还需要进行初始化。
初始化是指执行类的静态代码块和静态变量赋值操作。
这些操作只会执行一次,即在类加载时执行。
ClassLoader的工作机制是Java程序运行的基础。
通过ClassLoader,Java程序可以动态加载类,实现插件化、热部署等功能。
ClassLoader详解目录1.什么是C LASS L OADER (2)2.C LASS L OADER的层次 (2)3.C LASS L OADER加载C LASS的过程 (5)4.类加载器的顺序 (5)5.JVM是如何来建立类加载器的结构 (6)6.如何实现在运行时的动态载入和更新 (9)7.为什么要扩展C LASS L OADER (14)8.C LASS L OADER树和委托模型 (14)9.U NLOADING?R ELOADING? (15)10.由名字空间引发的 (16)11.类的查询 (18)12.一些重要的方法 (20)13.怎么组装这些方法 (21)14.J AV A 2中C LASS L OADER 的变动 (21)15.类与数据 (22)16.类加载器如何工作? (23)17.名词解释 (27)18.T IPS (27)19.类加载原则概括: (29)20.问题 (29)21.其他 (34)1.什么是ClassLoader与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。
当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM 里头运行,负责加载Java class的这部分就叫做Class Loader。
JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,Bootstrap ClassLoader是用本地代码实现的,它负责加载核心Java Class(即所有java.*开头的类)。
另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由Bootstrap ClassLoader加载;其中Extension ClassLoader负责加载扩展的Java class(例如所有javax.*开头的类和存放在JRE的ext目录下的类),Application ClassLoader负责加载应用程序自身的类。
术语“类加载”指的是找出一个给定类名的字节所在的位置并且将这些字节转换成Java类实例的过程。
2.ClassLoader的层次bootstrap classloader|extension classloader|app classloaderapp classloader 的parent是extension classloader,extension classloader的parent 是bootstrap classloader,bootstrap classloader的parent 是Null。
继承结构:Bootstrap ClassLoader|__URLClassLoader|__ExtClassLoader|__AppClassLoaderBootstrap classloader:引导(也称为原始)类加载器,它负责加载Java的核心类。
在Sun的JVM中,在执行java的命令中使用-Xbootclasspath选项或使用- D 选项指定sun.boot.class.path系统属性值可以指定附加的类。
这个加载器的是非常特殊的,它实际上不是ng.ClassLoader的子类,而是由JVM自身实现的。
大家可以通过执行以下代码来获得bootstrap classloader加载了那些核心类库:URL[] urls=uncher.getBootstrapClassPath().getURLs();for (int i = 0; i < urls.length; i++) {System.out.println(urls[i].toExternalForm());}在我的计算机上的结果为:file:/D:/jre1.5.0_06/lib/rt.jarfile:/D:/jre1.5.0_06/lib/i18n.jarfile:/D:/jre1.5.0_06/lib/sunrsasign.jarfile:/D:/jre1.5.0_06/lib/jsse.jarfile:/D:/jre1.5.0_06/lib/jce.jarfile:/D:/jre1.5.0_06/lib/charsets.jarfile:/D:/jre1.5.0_06/classes这时大家知道了为什么我们不需要在系统属性CLASSPA TH中指定这些类库了吧,因为JVM在启动的时候就自动加载它们了。
Extension classloader:扩展类加载器,它负责加载JRE的扩展目录(JA V A_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的)中JAR的类包。
这为引入除Java核心类以外的新功能提供了一个标准机制。
因为默认的扩展目录对所有从同一个JRE中启动的JVM都是通用的,所以放入这个目录的JAR 类包对所有的JVM和app classloader都是可见的。
在这个实例上调用方法getParent()总是返回空值null,因为引导加载器bootstrap classloader不是一个真正的ClassLoader实例。
所以当大家执行以下代码时:System.out.println(System.getProperty("java.ext.dirs"));ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent(); System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());结果为:D:\jre1.5.0_06\lib\extThe parent of extension classloader : nullextension classloader是app classloader的parent,而bootstrap classloader是extension classloader的parent,但它不是一个实际的classloader,所以为null。
App classloader:应用(也称为系统)类加载器,它负责在JVM被启动时,加载来自在命令java中的-classpath或者java.class.path系统属性或者CLASSPA TH 操作系统属性所指定的JAR类包和类路径。
总能通过静态方法ClassLoader.getSystemClassLoader()找到该类加载器。
如果没有特别指定,则用户自定义的任何类加载器都将该类加载器作为它的父加载器。
执行以下代码即可获得:System.out.println(System.getProperty("java.class.path"));输出结果则为用户在系统属性里面设置的CLASSPA TH。
classloader 加载类用的是全盘负责委托机制。
所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入;委托机制则是先让parent(父)类加载器(而不是super,它与parent classloader类不是继承关系)寻找,只有在parent找不到的时候才从自己的类路径中去寻找。
此外类加载还采用了cache机制,也就是如果cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache,这就是为什么我们修改了Class但是必须重新启动JVM才能生效的原因。
3.ClassLoader加载Class的过程1.检测此Class是否载入过(即在cache中是否有此Class),如果有到8,如果没有到2。
2.如果parent classloader不存在(没有parent,那parent一定是bootstrap classloader了),到4。
3.请求parent classloader载入,如果成功到8,不成功到5。
4.请求jvm从bootstrap classloader中载入,如果成功到8。
5.寻找Class文件(从与此classloader相关的类路径中寻找)。
如果找不到则到7。
6.从文件中载入Class,到8。
7.抛出ClassNotFoundException。
8.返回Class.。
其中5、6步我们可以通过覆盖ClassLoader的findClass方法来实现自己的载入策略。
甚至覆盖loadClass方法来实现自己的载入过程。
4.类加载器的顺序先是bootstrap classloader,然后是extension classloader,最后才是app classloader。
大家会发现加载的Class越是重要的越在靠前面。
这样做的原因是出于安全性的考虑,试想如果app classloader“亲自”加载了一个具有破坏性的“ng.System”类的后果吧。
这种委托机制保证了用户即使具有一个这样的类,也把它加入到了类路径中,但是它永远不会被载入,因为这个类总是由bootstrap classloader来加载的。
大家可以执行一下以下的代码:System.out.println(System.class.getClassLoader());将会看到结果是null,这就表明ng.System是由bootstrap classloader加载的,因为bootstrap classloader不是一个真正的ClassLoader实例,而是由JVM实现的,正如前面已经说过的。
5.JVM是如何来建立类加载器的结构uncher,顾名思义,当你执行java命令的时候,JVM会先使用bootstrap classloader载入并初始化一个Launcher,执行下来代码:System.out.println("the Launcher's classloader is"+uncher.getLauncher().getClass().getClassLoader());结果为:the Launcher's classloader is null (因为是用bootstrap classloader加载,所以class loader为null)Launcher 会根据系统和命令设定初始化好class loader结构,JVM就用它来获得extension classloader和app classloader,并载入所有的需要载入的Class,最后执行java命令指定的带有静态的main方法的Class。