ClassLoader详解

合集下载

classloader.getresourceasstream(name)原理解析

classloader.getresourceasstream(name)原理解析

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 机制

classloader 机制

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 范围

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的原理,举出应用场景及工作实例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以前)

ClassLoader详解(JDK9以前)

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机制-回复问题:什么是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加载原理

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运行机制

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统一的对象格式。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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。

相关文档
最新文档