类加载器

用来加载Java类到Java虚拟机中。一般来说,Java虚拟机使用Java类的方式如下:Java 源程序(.java 文件)在经过Java编译器编译之后就被转换成字节码(.class 文件)。类加载器就是负责读取Java字节代码,并转换成 java.lang.Class类的一个实例。

Java应用环境中不同的class分别由不同的ClassLoader负责加载。
一个jvm中默认的类加载器有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader:

  • 引导类加载器Bootstrap ClassLoader     负责加载Java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等。
  • 扩展类加载器Extension ClassLoader     负责加载Java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class。
  • 应用类加载器App ClassLoader             负责加载当前Java应用的classpath中的所有类。

类加载器的委托机制

当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?每个ClassLoader本身只能分别加载特定位置和目录中的类,但它们可以委托其他的类装载器去加载类,这就是类加载器的委托模式。

加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。

而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。类装载器一级级委托到BootStrap类加载器,当BootStrap无法加载当前所要加载的类时,然后才一级级回退到子孙类装载器去进行真正的加载。当回退到最初的类装载器时,如果它自己也不能完成类的装载,那就应报告ClassNotFoundException异常。

JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述:

自定义类加载器

由于一些特殊的需求,我们可能需要定制ClassLoader的加载行为,这时候就需要自定义ClassLoader了。自定义ClassLoader需要继承ClassLoader抽象类,重写findClass方法。这个方法定义了ClassLoader查找class的方式。因为类加载器是基于委托机制,它会自动向父类加载器委托,如果父类没有找到,就会再去调用我们重写的findClass方法加载。

1.定义一个需要被加载的类

 import java.util.Date;
public class ClassTest extends Date{
public Sting toSring() {
return"hello,java!";
}
}

2.定义一个用来加密字节码的类

 import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream; public class ClassEncrypt extends MyClassLoader{
public static void main(String[] args) throws IOException {
//要加密的字节码文件路径
String srcPath="F:\\Workspaces\\MyEclipse 10\\classload\\bin\\test_classload\\ClassTest.class";
//加密之后输出的字节码文件路径
String destPath="F:/ClassTest.class";
FileInputStream fis=new FileInputStream(srcPath);
FileOutputStream ofs=new FileOutputStream(destPath);
cypher(fis, ofs);
fis.close();
ofs.close();
}
//按字节异或
private static void cypher(InputStream in,OutputStream out) throws IOException{
int b=-1;
while((b=in.read())!=-1){
out.write(b^0xff);
}
}
}

3.自定义类加载器

 import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream; public class MyClassLoader extends ClassLoader{ @SuppressWarnings("deprecation")
@Override
protected Class findClass(String name) throws ClassNotFoundException {
try {
//需要加载的.class字节码的位置
String classPath="D:/ClassTest.class"; FileInputStream fis=new FileInputStream(classPath);
ByteArrayOutputStream bos=new ByteArrayOutputStream();
cypher(fis, bos);
fis.close();
byte[] bytes=bos.toByteArray();
return defineClass(bytes, 0, bytes.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return super.findClass(name);
} private static void cypher(InputStream in,OutputStream out) throws IOException{
int b=-1;
while((b=in.read())!=-1){
out.write(b^0xff);
}
}
}

4.测试类

 import java.lang.reflect.Method;
import java.util.Date; public class Test {
public static void main(String[] args) throws Exception {
Class clazz=new MyClassLoader().loadClass("test_classload.ClassTest");
//父类引用
Date d1 = (Date)clazz.newInstance();
System.out.println(d1);
//反射调用
Method m1 = Class.forName("test_classload.ClassTest").getMethod("toString", null);
System.out.println(m1.invoke(Class.forName("test_classload.ClassTest").newInstance(), null)); }
}

java-类加载器的更多相关文章

  1. java笔记--理解java类加载器以及ClassLoader类

    类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...

  2. java类加载器深入研究

    看了下面几篇关于类的加载器的文章,豁然开朗.猛击下面的地址开始看吧. Java类加载原理解析      深入探讨 Java 类加载器 分析BootstrapClassLoader/ExtClassLo ...

  3. 深入探讨 Java 类加载器

    转自:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 类加载器(class loader)是 Java™中的一个很重要的概念.类 ...

  4. JAVA 类加载器 第14节

    JAVA 类加载器 第14节 今天我们将类加载机制5个阶段中的第一个阶段,加载,又叫做装载.为了阅读好区分,以下都叫做装载. 装载的第一步就是要获得二进制的字节流,它可以从读.class文件获得,也可 ...

  5. 深入探讨 Java 类加载器[转]

    原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html 类加载器(class loader)是 Java™ ...

  6. 转载:深入探讨 Java 类加载器

    转载地址 : http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 深入探讨 Java 类加载器 类加载器(class loader) ...

  7. Java类加载器详解

    title: Java类加载器详解date: 2015-10-20 18:16:52tags: JVM--- ## JVM三种类型的类加载器- 我们首先看一下JVM预定义的三种类型类加载器,当一个 J ...

  8. 一篇文章读懂Java类加载器

    Java类加载器算是一个老生常谈的问题,大多Java工程师也都对其中的知识点倒背如流,最近在看源码的时候发现有一些细节的地方理解还是比较模糊,正好写一篇文章梳理一下. 关于Java类加载器的知识,网上 ...

  9. Java类加载器的工作原理

    Java类加载器的作用就是在运行时加载类.Java类加载器基于三个机制:委托.可见性和单一性.委托机制是指将加载一个类的请求交给父类加载 器,如果这个父类加载器不能够找到或者加载这个类,那么再加载它. ...

  10. 深入理解Java类加载器(ClassLoader)

    深入理解Java类加载器(ClassLoader) Java学习记录--委派模型与类加载器 关于Java类加载双亲委派机制的思考(附一道面试题) 真正理解线程上下文类加载器(多案例分析) [jvm解析 ...

随机推荐

  1. ubuntu远程桌面连接windows系统(转)

    现在用ubuntu系统,公司买了个windows的服务器,需要给配置一套环境,来回跑很麻烦,就想windows下可以的远程桌面,linux应该也有. 现在自己的ubuntu13.10,无法进入桌面的& ...

  2. easyui 中datagrid 点击行的事件

    $('#datagrid 的ID').datagrid({                onClickRow:function(index,data)                {        ...

  3. Android获取时间

    java代码: import java.text.SimpleDateFormat;SimpleDateFormat formatter = new SimpleDateFormat ('yyyy年M ...

  4. 安卓app中嵌入一个H5页面,当手机系统设置字体变大时,如何使H5页面的字体不会随用户自己调整的系统字体变化而变化?

    webview.getSettings().setTextZoom(100);WebView加上这个设置后,WebView里的字体就不会随系统字体大小设置发生变化了. https://segmentf ...

  5. Matlab(2) -- Find()函数

    转自:http://www.matlabsky.com/thread-4228-1-1.html find函数:用于查询非零元素的行和列标志 语法: ind = find(X) ind = find( ...

  6. touchstart,touchmove判断手机中滑屏方向

    滑动屏幕    touchstart:接触屏幕时触发,touchmove:活动过程触发,touchend:离开屏幕时触发 首先获取手接触屏幕时的坐标X,Y //获取接触屏幕时的X和Y$('body') ...

  7. mongo基本操作

    创建数据库文件的存放位置,比如d:/mongodb/data/db.启动mongodb服务之前需要必须创建数据库文件的存放文件夹,否则命令不会自动创建,而且不能启动成功. 打开cmd(windows键 ...

  8. Thinkphp 学习笔记

    前后台配置: 在根目录文件夹中创建一个Conf文件夹 Conf文件夹下建立一个config.php文件,里面存放公共配置信息,方便前后台调用. 简单定义404页面 伪静态去除.html Config中 ...

  9. mysql在ubuntu下的安装

    如果是调用的apt-get 那么应该是sudo apt-get install mysql-server-core-5.6  mysql-server-5.6 mysql-common-5.6 mys ...

  10. MVC3在IIS7.5发布(部署)报403.14错误的解决办法

    MVC3在IIS7.5发布(部署)报403.14错误的解决办法     错误现象: 报403.14 forbidden错误 web服务器被配置为不列出此目录的内容. 解决办法: 检查站点的处理程序映射 ...