一、类加载器结构

  

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

浅谈JVM-类加载器结构与双亲委派机制的更多相关文章

  1. java的类加载器体系结构和双亲委派机制

    类加载器将字节码文件加载到内存中,同时在方法区中生成对应的java.land.class对象  作为外部访问方法区的入口. 类加载器的层次结构: 引导类加载器<-------------扩展类加 ...

  2. 结合JVM 浅谈Java 类加载器(Day_03)

    所谓错过,不是错了,而是过了. 什么是JAVA类加载? Class对象由JVM自动产生,每当一个类被加载时,JVM就自动为其生成一个Class对象,通过Class对象可以获得类的相关信息.将类信息读取 ...

  3. Java的类加载器种类(双亲委派)

    Java类加载器采用双亲委派模型: 1.启动类加载器:这个类加载器负责放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别 ...

  4. [jvm] -- 类加载器及双亲委派模板篇

    类加载器 JVM 中内置了三个重要的 ClassLoader BootstrapClassLoader(启动类加载器):最顶层的加载类,由C++实现,负责加载 %JAVA_HOME%/lib目录下的j ...

  5. 深入JVM类加载器机制,值得你收藏

    先来一道题,试试水平 public static void main(String[] args) { ClassLoader c1 = ClassloaderStudy.class.getClass ...

  6. JVM类加载与双亲委派机制被打破

    前言 前文已经讲了虚拟机将java文件编译成class文件后的格式:JVM虚拟机Class类文件研究分析 java文件经过编译,形成class文件,那么虚拟机如何将这些Class文件读取到内存中呢? ...

  7. java类加载过程以及双亲委派机制

    前言:最近两个月公司实行了996上班制,加上了熬了两个通宵上线,状态很不好,头疼.牙疼,一直没有时间和精力写博客,也害怕在这样的状态下写出来的东西出错.为了不让自己荒废学习的劲头和习惯,今天周日,也打 ...

  8. JVM探究(一)谈谈双亲委派机制和沙箱安全机制

    JVM探究 请你谈谈你对JVM的理解?java8虚拟机和之前的变化gengxin? 什么是OOM,什么是栈溢出StackOverFlowError JVM的常用调优参数有哪些? 内存快转如何抓取,怎么 ...

  9. java安全沙箱(一)之ClassLoader双亲委派机制

    java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件检验器 内置于Java虚拟机(及语言)的安全特性 安全管理器及J ...

随机推荐

  1. 自定义ISO结构

    流程: 1.OS安装 1.1 网卡配置 1.2 密码 1.3 语言 1.4 时区 1.5 分区 1.6 rpms ... 2.软件安装 2.1 BIC Server 2.2 APP Server 2. ...

  2. i8042 键盘控制器-------详细介绍

    [转]http://shanzy.bokee.com/834368.html ps/2 键盘硬件概述 对于驱动来说,和键盘相关的最重要的硬件是两个芯片.一个是 intel 8042 芯片,位于主板上, ...

  3. 142.Linked List Cycle II---双指针

    题目链接 题目大意:141题目的扩展,给出单链表,判断是否有环,如果有环,找出环的开始的结点,如果没有环,返回null. 法一(借鉴):在已经找出单链表环的基础上再找开始结点,要时刻记住这个环不一定是 ...

  4. 56.Merge Intervals---贪心---《编程之美》2.19区间重合判断

    题目链接:https://leetcode.com/problems/merge-intervals/description/ 题目大意:给出一串list,里面装interval类,这个类里有star ...

  5. Keras自定义评估函数

    1. 比较一般的自定义函数: 需要注意的是,不能像sklearn那样直接定义,因为这里的y_true和y_pred是张量,不是numpy数组.示例如下: from keras import backe ...

  6. mysql视图学习总结(转)

    一.使用视图的理由是什么?1.安全性.一般是这样做的:创建一个视图,定义好该视图所操作的数据.之后将用户权限与视图绑定.这样的方式是使用到 了一个特性:grant语句可以针对视图进行授予权限.2.查询 ...

  7. Linux 用户篇——用户管理命令之useradd、passwd、userdel、usermod

    一.用户重要,用户管理命令同样重要 用户是Linux系统安全的核心,每个登录Linux系统的用户都会分配相应的权限,这些权限取决于能否访问系统中各种对象.而管理这些用户的相关信息离不开用户管理命令,比 ...

  8. gtk+学习笔记(二)

    如何创建一个按钮呢,直接贴代码把,有详细的注释. #include<gtk/gtk.h> gint data_count=; void on_button_clicked (GtkWidg ...

  9. 关于HTML5 boilerplate 的一些笔记

    最近在研究HTML5 boilerplate的模版,以此为线索可以有条理地学习一些前端的best practice,好过在W3C的文档汪洋里大海捞针……啊哈哈哈…… 开头的IE探测与no-js类是什么 ...

  10. day5时间复杂度

    时间复杂度       (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花 ...