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参数所指定的路径中的,并且是虚拟机识别 ...
随机推荐
- asp.net母版-页脚制作
1.母版创建流程略过 2.创建母版页css:Site.css body{ } .linkButton{ text-decoration:none; color:whitesmoke; } 3.母版页添 ...
- SQLServer待优化语句查询
SELECT top 100 (total_elapsed_time / execution_count)/1000 N'平均时间ms' ,total_elapsed_time/1000 N'总花费时 ...
- 制作个人开发IDE
1.打开VS2013,新建项目: 2.点击下一步,下一步.到达例如以下界面: 3.下一步 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R ...
- How Many Tables-并查集
id=19354" target="_blank" style="color:blue; text-decoration:none">HDU - ...
- VS2010编译OpenSSL(两个版本)
第一个版本: 编译工具 VS2010 OpenSSL版本 openssl-1.0.0a 下载 OpenSSL http://www.openssl.org/ 下载 from http://www.ac ...
- Spark源码分析之六:Task调度(二)
话说在<Spark源码分析之五:Task调度(一)>一文中,我们对Task调度分析到了DriverEndpoint的makeOffers()方法.这个方法针对接收到的ReviveOffer ...
- php 字符串内容是数组格式 转换成数组
一个简单的应用.. 例, $str = "array( 'USD'=>'1', 'GBP'=>'0.6494', 'EUR'=>'0.7668' ,'JPY'= ...
- PowerBuilder -- 指定重复的列不显示
- android shareSDK 微博分享案例
android shareSDK 微博分享案例 ShareSDK APP_KEY 219b1121fc68 腾讯微博 key 801517904 secret bfba83ae253c8f38dabe ...
- 通过srvctl add命令添加database信息到srvctl管理器
================================================通过srvctl add命令添加database信息到srvctl管理器================ ...