分析Java的类加载器与ClassLoader(二):classpath与查找类字节码的顺序,分析ExtClassLoader与AppClassLoader的源码
先回顾一下classpath
classpath的作用:
classpath的作用是指定查找类的路径:当使用java命令执行一个类(类中的main方法)时,会从classpath中进行查找这个类。
指定classpath的方式一:
设置环境变量CLASSPATH,多个路径之间使用英文的分号隔开,也可以指定为jar包路径。
示例:CLASSPATH=c:/myclasses/;c/mylib/aa.jar;c:/mylib/bb.jar;.
注意:在Windows中不区分大小写,所以指定的环境变量名为classpath或是ClassPath都一样。
指定classpath的方式二:
在执行java命令时通过-classpath参数指定。
示例:java -classpath c:/myclasses/;c:/mylib/aa.jar cn.itcast.MainApp
注意:这样就会只是用这个参数指定的classpath,找不到类就报错,不会使用CLASSPATH环境变量!
指定classpath时各个路径的顺序:
试验的结论是 按classpath中指定的顺序,先从前面的路径中查找,如果找不到,在从下一个路径中查找,直到找到类字节码或是报NoClassDefFoundError。
另外一种指定类路径方式:
把类字节码文件打成jar包,并放到JRE的lib/ext/目录下,这样在执行时就可以直接找到这个类而不需要指定classpath了。
类加载器与classpath
从上一个文章中我们知道了类加载器默认使用三个:
1,Bootstrap ClassLoader,启动类加载器,负责加载核心Class(即所有java.*开头的Class)。
2,Extension ClassLoader,扩展类加载器,负责加载存放在JRE的lib/ext/目录下的jar包中的Class。
3,Application ClassLoader,应用程序类加载器,负责加载应用程序自身的类(CLASSPATH目录中的Class)。
分析ExtClassLoader
Extension ClassLoader负责加载扩展类路径中的类(默认为JRE的lib/ext/目录) ,也就是说只要把jar包放到这个目录中,就可以直接使用里面的类字节码而不需要指定classpath !注意这要求一定要在这个目录中放jar包,直接把.class文件放到这个目录中不行。分析一下源码(sun.misc.Launcher$ExtClassLoader类):
static class ExtClassLoader extends URLClassLoader {
private File[] dirs; // 先看这个方法
public static ExtClassLoader getExtClassLoader() throws IOException {
// 调用getExtDirs()方法获取配置的扩展类路径
final File[] dirs = getExtDirs();
try {
// 使用getExtDirs()方法返回的路径生成一个新的ClassLoader实例
return (ExtClassLoader) AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws IOException {
int len = dirs.length;
for (int i = 0; i < len; i++) {
MetaIndex.registerDirectory(dirs[i]);
}
return new ExtClassLoader(dirs);
}
});
} catch (java.security.PrivilegedActionException e) {
throw (IOException) e.getException();
}
} // 再看这个方法
private static File[] getExtDirs() {
// 获取配置的扩展类路径
String s = System.getProperty("java.ext.dirs");
File[] dirs;
if (s != null) {
StringTokenizer st = new StringTokenizer(s, File.pathSeparator);
int count = st.countTokens();
dirs = new File[count];
for (int i = 0; i < count; i++) {
dirs[i] = new File(st.nextToken());
}
} else {
dirs = new File[0];
}
return dirs;
} // 其他代码略
...
}
Application ClassLoader负责加载CLASSPATH目录中的Class ,也就是说classpath是给这个类加载器用的。分析一下源码(sun.misc.Launcher$AppClassLoader类):
static class AppClassLoader extends URLClassLoader { public static ClassLoader getAppClassLoader(final ClassLoader extcl) throws IOException {
// 获取配置的classpath路径
// 注1:可以通过设置classpath环境变量改变java.class.path的值。
// 注2:也可以在程序中使用System.setProperty("java.class.path", "newpath")改变java.class.path的值。
final String s = System.getProperty("java.class.path");
final File[] path = (s == null) ? new File[0] : getClassPath(s); // 使用classpath中的路径生成一个新的ClassLoader实例并返回
return (AppClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
URL[] urls = (s == null) ? new URL[0] : pathToURLs(path);
return new AppClassLoader(urls, extcl);
}
});
} // 其他代码略
...
}
当AppClassLoader遇上ExtClassLoader
如果JRE的lib/ext/目录下的jar包有某个类,我们指定的classpath中也有这个类,会怎么样呢?想想类加载查找类字节码的策略!结论是会执行lib/ext/xx.jar中的类! 因为类加载器使用委托模式进行类加载,并且ExtClassLoader是AppClassLoader的上级,所以AppClassLoader会先让ExtClassLoader加载。如果父的类加载器没有找到,自己才会加载。
结论:
1,把jar包放到扩展类路径中就可以直接使用其中的类(默认是JRE的lib/ext/目录)
2,classpath是给AppClassLoader配置的。
3,如果扩展类路径中有某个类,classpath中也有这个类,则会使用扩展类路径中的类。
http://www.tuicool.com/articles/bQFnqmi
分析Java的类加载器与ClassLoader(二):classpath与查找类字节码的顺序,分析ExtClassLoader与AppClassLoader的源码的更多相关文章
- Java:类加载器(ClassLoader)
听上去很高端,其实一般自定义类加载器不需要用户去实现解析的过程,只要负责实现获取类对应的.class字节流部分就ok了,摘录深入理解Java虚拟机的一段话 虚拟机设计团队把类加载阶段中的“通过一个类的 ...
- 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)
转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...
- Java基础-类加载机制与自定义类Java类加载器(ClassLoader)
Java基础-类加载机制与自定义类Java类加载器(ClassLoader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于类加载器的概念和分类我就不再废话了,因为我在之前的笔 ...
- java笔记--理解java类加载器以及ClassLoader类
类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...
- JVM的艺术—类加载器篇(二)
分享是价值的传递,喜欢就点个赞 引言 今天我们继续来深入的剖析类加载器的内容.上节课我们讲了类加载器的基本内容,没看过的小伙伴请加关注.今天我们继续. 什么是定义类加载器和初始化类加载器? 定义类加载 ...
- Java的类加载器
一.类加载器的概念 类加载器(class loader)用来加载 Java 类到 Java 虚拟机中.一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 ...
- 7. 通过JDBC源码来分析线程上下文类加载器以及SPI的使用
目录 1. 什么是全盘负责委托机制 2. 为什么需要有线程上下文类加载器 2.1 使用JDBC的例子,分析为什么双亲委托机制不能实现要求 2.2 线程上下文类加载器的作用 3. 线程上下文类加载器的使 ...
- java自定义类加载器
前言 java反射,最常用的Class.forName()方法.做毕设的时候,接收到代码字符串,通过 JavaCompiler将代码字符串生成A.class文件(存放在classpath下,也就是ec ...
- 深入理解Java虚拟机 - 类加载器
引子: 类加载器(classloader)是独立于虚拟机之外,可以独立实现的代码模块. OSGi使用了类加载器的这一特点实现其热插拔的特性 Java同C++等语言不通, ...
随机推荐
- Oracle、DB2、SQLSERVER、Mysql、Access分页SQL语句梳理
最近把平时在项目中常用到的数据库分页sql总结了下.大家可以贴出分页更高效的sql语句.sqlserver分页 第一种分页方法 需用到的参数: pageSize 每页显示多少条数据 pageNumbe ...
- jsp页面在IE8下文本模式自动为“杂项(Quirks)”导致页面显示错位
最近在修改网站的响应式的页面时,由于都是套样式页面,修改过程都是粘贴复制,导致了一些细节问题在IE8下暴露出来: 遇到的问题就是在在Chrome,火狐页面都正常,唯独在IE8下页面样式显示乱样了,但是 ...
- swift-计算器(斯坦福公开课)
看了斯坦福老头的课,真心觉得,我的中文怎么也变的这么垃圾了.是关于iOS8的课程,用swift写的,一个计算器应用的制作,看看人家的课,再看看咱们学校的课(不过垃圾学校,纯粹觉得大学浪费了),废话啊, ...
- Warning: Attempt to present * on * which is already presenting *
Warning: Attempt to present (要被presented的控制器) on (哪个控制器来presenting) which is already presenting (已经 ...
- Objective-C 学习笔记(Day 2)
------------------------------------------- 如何根据题目准确完整清晰的声明一个类并实现给定的行为 /* //下面这个程序教大家如何根据题目去声明一个类,并 ...
- C#与C++相比较之STL篇
引言 Program into Your Language, Not in It--<代码大全>.如何深入一门语言去编程?我认为有三步:熟悉它:知道它的局限性:扩展它.如何熟悉?不必说,自 ...
- QQ登录网站接入
QQ网站登录是一个非常常用的功能,网上有很多的资料,在此只做一个整理: QQ登录接入也在不断的升级,目前我发布的是2.1,很多资料里显示的那些繁杂的步骤已经不需要了: 第一步需要先申请,申请地址如下: ...
- Java知识总结--Servlet&JSP
1MVC的各个部分都有哪些技术来实现?如何实现? MVC是Model-View-Controller的简写.“Model”代表的是应用的业务逻辑(通过JavaBean,EJB组件实现),“View”是 ...
- mysql 之权限介绍
转自:http://tech.it168.com/a2010/0114/837/000000837456_all.shtml 一.MySQL授权表概述首先从全局开始,如果全局的是允许的,即在 user ...
- Asp.net Gridview导出Excel
前台页面放一个GridView什么的就不说了,要注意的是在 <%@ Page Language="C#" AutoEventWireup="true" C ...