一、类加载器结构

  

1、引导类加载器(bootstrap class loader)

  它用来加载Java的核心库(JAVA_HOME/jre/lib/rt.jar),是用原声代码来实现的,并不继承自java.lang.Classloader。

  加载扩展类和应用程序类加载器。并制定指定的父类加载器。

2、扩展类加载器(extensions class loader)

  用来加载Java的扩展库(JAVA_HOME/JRE/EXT/*.jar),Java虚拟机的实现会提供一个扩展库目录。该加载器在此目录里面查找并加载Java类。

3、应用程序类(application class loader)

  它根据Java应用程序的类路径(classpath,java.class.path)路径类。一般来说,系统(应用程序)类都是由它来加载。

4、自定义类

  继承java.lang.ClassLoader类的方式实现自己的类加载器,以满足一些特殊的需求。

二、类加载作用与API

三、双亲委派机制

  双亲委派机制实际上就是使用代理模式(交给其它类加载器完成)。

  某个特定的类加载器在接到加载器请求时,首先将加载任务委托给父加载器,一直高层次加载器委托。若加载器可完成其加载任务,就成功返回;只有父加载器无法完成此加载任务,才自己加载。

  作用:保证java核心库的类型安全。

  思考:如何保证安全?假设我们自定义了java.lang.String类,这属于系统类是不允许被加载的。首先Application Class Loader向上抛,直到抛到Bootstrap Class Loader类,然后Bootstrap Class Loader一看,咦,我核心库里面有java.lang.String类,就直接把rt.jar的代码加载进去。我们自定义的java.lang.String就孤单的被抛弃了。

四、自定义类加载器

 public class FileSystemClassLoader extends ClassLoader {

     //HelloWorld   --> f:/myjava/  HelloWorld.class
private String rootDir; public FileSystemClassLoader(String rootDir){
this.rootDir = rootDir;
} @Override
protected Class<?> findClass(String name) throws ClassNotFoundException { Class<?> c = findLoadedClass(name); //应该要先查询有没有加载过这个类。如果已经加载,则直接返回加载好的类。如果没有,则加载新的类。
if(c!=null){
return c;
}else{
ClassLoader parent = this.getParent();
try {
c = parent.loadClass(name); //委派给父类加载
} catch (Exception e) {
// e.printStackTrace();
} if(c!=null){
return c;
}else{
byte[] classData = getClassData(name);
if(classData==null){
throw new ClassNotFoundException();
}else{
c = defineClass(name, classData, 0,classData.length);
}
} } return c; } private byte[] getClassData(String classname){ //com.bjsxt.test.User d:/myjava/ com/bjsxt/test/User.class
String path = rootDir +"/"+ classname.replace('.', '/')+".class"; // IOUtils,可以使用它将流中的数据转成字节数组
InputStream is = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try{
is = new FileInputStream(path); byte[] buffer = new byte[1024];
int temp=0;
while((temp=is.read(buffer))!=-1){
baos.write(buffer, 0, temp);
} return baos.toByteArray();
}catch(Exception e){
e.printStackTrace();
return null;
}finally{
try {
if(is!=null){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(baos!=null){
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} }
}

测试类:当同一个类被不同加载器加载的时候,JVM认为它们不是同一个类。

 package com.aaron.classloader;

 public class Test {
public static void main(String[] args) throws Exception{
FileSystemClassLoader loader = new FileSystemClassLoader("f:/myjava");
FileSystemClassLoader loader2 = new FileSystemClassLoader("f:/myjava"); Class<?> c = loader.loadClass("HelloWorld");
Class<?> c2 = loader.loadClass("HelloWorld");
Class<?> c3 = loader2.loadClass("HelloWorld"); Class<?> c4 = loader2.loadClass("java.lang.String");
Class<?> c5 = loader2.loadClass("com.aaron.classloader.HelloWorld"); System.out.println(c.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode()); //同一个类,被不同的加载器加载,JVM认为也是不相同的类
System.out.println(c4.hashCode());
System.out.println(c4.getClassLoader());//引导类加载器
System.out.println(c3.getClassLoader()); //自定义的类加载器
System.out.println(c5.getClassLoader()); //系统默认的类加载器 }
}

测试结果

深入学习参考:http://blog.csdn.net/zhoudaxia/article/details/35824249

最新文章

  1. python基础之day2
  2. 自己动手写ORM的感受
  3. js之事件冒泡和事件捕获
  4. 手动内存管理与ARC互相转换问题
  5. FHS目录配置下,常见的几个问题及解答
  6. C# 乘法口诀表的实现方法
  7. android学习日记27--Dialog使用及其设计模式
  8. 201521123097《Java程序设计》第五周学习总结
  9. c# Linq操作XML,查找节点数据
  10. 【spring】-- springboot配置全局异常处理器
  11. 常用adb 指令
  12. Jmeter-csv文件参数化
  13. mockjs使用
  14. 浅谈URI和URL
  15. Oracle 和 SQLSERVER 重新获取统计信息的方法
  16. 基于libnids的TCP数据流的还原(多线程实现) .
  17. DQL-联合查询
  18. BZOJ 1208: [HNOI2004]宠物收养所 SET的妙用
  19. 001profile条件化创建bean
  20. 一个字符串是否在另外一个字符串数组里 Array.Exists 的用法 Array.IndexOf 用法

热门文章

  1. Linux端口占用
  2. (MHA+MYSQL-5.7增强半同步)高可用架构设计与实现
  3. Kaggle:Titanic: Machine Learning from Disaster
  4. 1、量化投资—为什么选择Python?
  5. 【hdoj_1250】Hat&#39;s Fibonacci(大数)
  6. [笔记] 几个前端bug的解决方案
  7. 【原创】Scrapyd 的 .net 客户端
  8. 易普优APS应用案例:线束行业生产计划排产
  9. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) G - Xor-matic Number of the Graph 线性基好题
  10. openssl解析国密X509证书