java-类加载器
类加载器
用来加载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-类加载器的更多相关文章
- java笔记--理解java类加载器以及ClassLoader类
类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...
- java类加载器深入研究
看了下面几篇关于类的加载器的文章,豁然开朗.猛击下面的地址开始看吧. Java类加载原理解析 深入探讨 Java 类加载器 分析BootstrapClassLoader/ExtClassLo ...
- 深入探讨 Java 类加载器
转自:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 类加载器(class loader)是 Java™中的一个很重要的概念.类 ...
- JAVA 类加载器 第14节
JAVA 类加载器 第14节 今天我们将类加载机制5个阶段中的第一个阶段,加载,又叫做装载.为了阅读好区分,以下都叫做装载. 装载的第一步就是要获得二进制的字节流,它可以从读.class文件获得,也可 ...
- 深入探讨 Java 类加载器[转]
原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html 类加载器(class loader)是 Java™ ...
- 转载:深入探讨 Java 类加载器
转载地址 : http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 深入探讨 Java 类加载器 类加载器(class loader) ...
- Java类加载器详解
title: Java类加载器详解date: 2015-10-20 18:16:52tags: JVM--- ## JVM三种类型的类加载器- 我们首先看一下JVM预定义的三种类型类加载器,当一个 J ...
- 一篇文章读懂Java类加载器
Java类加载器算是一个老生常谈的问题,大多Java工程师也都对其中的知识点倒背如流,最近在看源码的时候发现有一些细节的地方理解还是比较模糊,正好写一篇文章梳理一下. 关于Java类加载器的知识,网上 ...
- Java类加载器的工作原理
Java类加载器的作用就是在运行时加载类.Java类加载器基于三个机制:委托.可见性和单一性.委托机制是指将加载一个类的请求交给父类加载 器,如果这个父类加载器不能够找到或者加载这个类,那么再加载它. ...
- 深入理解Java类加载器(ClassLoader)
深入理解Java类加载器(ClassLoader) Java学习记录--委派模型与类加载器 关于Java类加载双亲委派机制的思考(附一道面试题) 真正理解线程上下文类加载器(多案例分析) [jvm解析 ...
随机推荐
- Android之简单了解Bitmap显示图片及缓存图片
昨天我们学了如何连接网络,今天我们就学习一下如何从把网上图片显示到项目中 今天主要用到的是Bitmap 类 Bitmap是Android系统中的图像处理的最重要类之一.用它可以获取图像文件信息,进行图 ...
- Citrix Reciver提示安装程序集错误
打开注册表查找是否有RegistrySizeLimit这个项目,如果有更改成8个f,如果没有就需要手动建立一个之后输入8个f,操作方法如下: 到了 HKEY_LOCAL_MACHINE\SYSTEM\ ...
- js高级选择器querySelector和querySelectorAll
querySelector 和 querySelectorAll 方法是 W3C Selectors API规范中定义的.他们的作用是根据 CSS 选择器规范,便捷定位文档中指定元素. 目前几乎主流浏 ...
- Erp中的ATP和CTP是什么?两者有什么区别?
可用量承诺(Available to Promise,ATP),是一种库存匹配模型,意在最大限度地利用库存产品对客户订单需求做出及时和准确的反应,缩短交货提前期.降低库存水准: 可用生产能力承诺(Ca ...
- JavaScript的继承
原型继承的实现 1 简化版本 function SuperClass(){...} function SubClass(){...} SubClass.prototype=new SuperClass ...
- Linux系统下的Nginx安装
nginx可以使用各平台的默认包来安装,本文是介绍使用源码编译安装,包括具体的编译参数信息. 正式开始前,编译环境gcc g++ 开发库之类的需要提前装好,这里默认你已经装好. ububtu平台编译环 ...
- 初试Nodejs——使用keystonejs创建博客网站2(修改模板)
上一篇(初试Nodejs——使用keystonejs创建博客网站1(安装keystonejs))讲了keystonejs的安装.安装完成后,已经具备了基本的功能,我们需要对页面进行初步修改,比如,增加 ...
- 【Lua】Lua的几点优化原则
Lua是一门以性能著称的脚本语言,被广泛的应用在很多方面,比如很多游戏的插件. 很多时候,没有必要去考虑性能的问题,不过,如果我们在开始编写代码的时候就以更适当,性能更高的方式与结构去组织代码,对于程 ...
- Mac删除.DS_Store文件
1.删除.DS_Store文件 sudo find ./ -name ".DS_Store" -depth -exec rm {} \; 2.禁止生成此文件 defaults wr ...
- MFC学习笔记
获取窗口句柄 FindWindow 根据窗口名获取 GetSafehWnd 取你程序所在窗口类的句柄 GetActiveWindow ...