Java之类加载器(Class Loader)
JVM默认有三个类加载器:
- Bootstrap Loader
Bootstrap Loader通常有C编写,贴近底层操作系统。是JVM启动后,第一个创建的类加载器。
- Extended Loader
Extended Loader由Java编写,由Bootstrap Loader创建。JVM启动后,第二个被创建的类加载器。在Oracle JDK中,对应sum.misc.Launcher$ExtClassLoader($表示内部类)。
- System Loader
System Loader由Java编写,同样由Bootstrap Loader创建。JVM启动后,第三给被创建的类加载器。在Oracle JDK中,对应sum.misc.Launcher$AppClassLoader。
JVM启动后,类加载器的创建顺序如下:
- JVM创建Bootstrap Loader;
- 由Bootstrap Loader创建Extended Loader;
- 设置Bootstrap Loader为Extended Loader的父类;
- 用Bootstrap Loader创建System Loader;
- 设置Extended Loader为System Loader的父类。
如下图:

从创建过程可见,类加载器间是有层级关系的。
当类加载器有加载任务时,会先把加载任务交给父加载器,如果父加载器无法加载,才由自己加载。所以加载类的时候,会以Bootstrap Loader → Extended Loader → System Loader的加载类。如果所有加载器加载类失败,抛出java.lang.NoClassDefFoundError异常。
每个类加载器,会到其指定的目录下,根据类名加载类文件。三个默认类加载器的指定目录保持在JVM的系统属性里。
|
Bootstrap Loader |
sun.boot.class.path 可以在编译时期,使用-bootclasspath指定。 |
|
Extended Loader |
java.ext.dirs |
|
System Loader |
java.class.path 可以在运行程序时,使用-cp指令覆盖CLASSPATH系统环境变量。 |
可以使用System.getProperty()方法获取实际值。
三个默认类加载器在程序启动后,就无法更改它们的搜索目录。如果在程序运行过程中,打算动态加载其他路径下的类,可以创建java.net.URLClassLoader实例,使用新的类加载器。
URLClassLoader类创建实例时,需要java.net.URL数组作为参数指定新的类加载搜索路径。
|
ClassLoader loader = new URLClassLoader(new URL[] {new URL(pathA), new URL(pathB)}); loader.loadClass(clzName); |
URLClassLoader类的实例,将由Bootstrap Loader创建,指定父加载器为System Loader。
由于使用URL协议,可以指定远程服务器上的类文件,使用本地路径时,注意添加前缀"file:/"。
类加载器可以使用loadClass()方法加载类,默认不会执行类的静态初始区块。但会在第一次新建该类实例的时候执行静态初始区块。
可以使用getParent()获取类加载器的父加载器。自定义对象默认用System Loader加载,可以使用Class.getClassLoader()获取加载该类的类加载器。
|
// 获取System Loader ClassLoader sysClassLoader = Empty.class.getClassLoader(); // 获取Extended Loader ClassLoader extClassLoader = sysClassLoader.getParent(); // 获取Bootstrap Loader ClassLoader bootClassLoader = extClassLoader.getParent(); System.out.println(sysClassLoader); System.out.println(extClassLoader); System.out.println(bootClassLoader); |
输入如下:
|
sun.misc.Launcher$AppClassLoader@73d16e93 sun.misc.Launcher$ExtClassLoader@15db9742 null |
获取Extended Loader的父加载器时,返回值为null,但并不代表它没父加载器。因为Bootstrap Loader通常由C实现,在Java中没实际类实例来表示,所有会显示null。
标准API的类(包括数组对象,包装器),都是由Bootstrap Loader加载的。
|
// 以下均输出null System.out.println(String.class.getClassLoader()); System.out.println(int[].class.getClassLoader()); System.out.println(Integer.class.getClassLoader()); System.out.println(Class.class.getClassLoader()); |
同一个类文件,由同一个类加载器(实际加载的那个类加载器,注意加载任务会先向父加载器传递)多次加载,只有一个Class实例;如果由不同的类加载器加载,会由不同的Class实例。
参考资料:《Java学习笔记》 第17章
Java之类加载器(Class Loader)的更多相关文章
- java自定义类加载器
前言 java反射,最常用的Class.forName()方法.做毕设的时候,接收到代码字符串,通过 JavaCompiler将代码字符串生成A.class文件(存放在classpath下,也就是ec ...
- Java虚拟机类加载器及双亲委派机制
所谓的类加载器(Class Loader)就是加载Java类到Java虚拟机中的,前面<面试官,不要再问我"Java虚拟机类加载机制"了>中已经介绍了具体加载class ...
- 深入探讨java的类加载器
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一.它使得 Java 类可以被动态加载到 Java 虚拟机中并执行.类加载器从 JDK 1.0 就出现了,最初是为了满足 Ja ...
- java 中类加载器
jar 运行过程和类加载机制有关,而类加载机制又和我们自定义的类加载器有关,现在我们先来了解一下双亲委派模式. java 中类加载器分为三个: BootstrapClassLoader 负责加载 ${ ...
- Java中的类加载器--Class loader
学习一下Java中的类加载器,这个是比较底层的东西,好好学习.理解一下. 一.类加载器的介绍 1.类加载器:就是加载类的工具,在java程序中用到一个类,java虚拟机首先要把这个类的字节码加载到内 ...
- java高新技术-类加载器
1.类加载器及委托机制的深入分析 > 类加载器的作用:一个java文件中的出现的类,首先要把这个类的字节码加载到内存中,这个类的信息放在硬盘的classPath下的class文件中, 把cla ...
- java面向对象--类加载器及Class对象
类加载器 jvm 和 类的关系 当调用 java命令运行一个java程序时,会启动一个java虚拟机进程.同一个jvm的所有线程.所有变量都处于同一个进程里,都使用该jvm进程的内存区. jvm进程终 ...
- Java的类加载器
一.类加载器的概念 类加载器(class loader)用来加载 Java 类到 Java 虚拟机中.一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 ...
- Java的类加载器种类(双亲委派)
Java类加载器采用双亲委派模型: 1.启动类加载器:这个类加载器负责放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别 ...
随机推荐
- 字符串(string)操作的相关方法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- (个人开源)ffpanel --ffmpeg的GUI,让ffmpeg离开黑黑的命令行
程序及源代码下载地址 :https://github.com/langsim/ffpanel
- PowerBuilder -- 未公开函数
原文:http://blog.csdn.net/happymagic/article/details/51077322 @.已知一个DW中的某列的列名(在字符串变量中),以获得这个列对象的DWO 方法 ...
- 模式识别开发之项目---基于opencv的手势识别
我使用OpenCV2.4.4的windows版本+Qt4.8.3+VS2010的编译器做了一个手势识别的小程序. 本程序主要使到了Opencv的特征训练库和最基本的图像处理的知识,包括肤色检测等等. ...
- 图像处理之基础---卷积及其快速算法的C++实现
头文件: /* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), zmjerry@163.com * * This program is free so ...
- 在mac下搭建java开发环境
刚刚从windows系统转到使用mac系统.感觉不是特别熟悉,须要一定的适应时间. 以下简介一下mac下搭建主要的java开发环境. 1.安装jdk 安装jdk1.7后,发现不须要进行环境变量配置,直 ...
- 【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA
[BZOJ4999]This Problem Is Too Simple! Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2 ...
- Mac版 Intellij IDEA 激活
第一步:修改这两个文件夹 进入跳转路径,输入 /private/etc/ 点击[前往] 同时加上: # Intellij IDEA0.0.0.0 account.jetbrains.com 第二部:在 ...
- wepy 实现 用户名登录与短信验证码登录
wepy 实现 用户名登录与短信验证码登录
- python数据分析之:数据清理,转换,合并,重塑(一)
DataFrame合并: merge运算是将一个或多个键将行链接起来.来看下面的这个例子: In [5]: df1=DataFrame({'key':['b','b','a','c','a','a', ...