public class MyTest16 extends ClassLoader {
private String classLoaderName;
private String fileExtension = ".class";
private String path; public MyTest16(String classLoaderName) {
super(); // 将系统类加载器当做该类加载器的父类加载器
this.classLoaderName = classLoaderName;
} public void setPath(String path){
this.path = path;
} public MyTest16(ClassLoader parent, String classLoaderName) {
super(parent); //显示指定该类的加载器的父类加载器
this.classLoaderName = classLoaderName;
} private byte[] loadClassData(String className) {
InputStream is = null;
byte[] data = null;
ByteArrayOutputStream baos = null; String classNameResult = className.replace(".", "\\"); System.out.println(classNameResult);
try {
//注意win和linux
this.classLoaderName = this.classLoaderName.replace(".", "\\");
//指定磁盘全路径
String fileUrl = classNameResult + this.fileExtension;
is = new FileInputStream(this.path + new File(fileUrl));
baos = new ByteArrayOutputStream();
int ch ;
while (-1 != (ch = is.read())) {
baos.write(ch);
}
// 字节数组输出流转换成字节数组
data = baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
is.close();
baos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return data;
} @Override
protected Class<?> findClass(String className) throws ClassNotFoundException { System.out.println("findClass invoked:" + className);
System.out.println("class loader name" + this.classLoaderName); byte[] data = this.loadClassData(className);
//返回Class对象
return this.defineClass(className, data, 0 , data.length);
} @Override
public String toString() {
return "[" + this.classLoaderName + "]";
} public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
// 创建自定义类加载器 名字“loader1” 父类加载器是系统类加载器
MyTest16 loader1 = new MyTest16("loader1");
//此路径为classPath,故 findClass方法不会被调用执行! 如果换个路径,不是classPath就会去执行了!
loader1.setPath("D:\\eclipse_pj\\dianshang\\jvmTest\\out\\production\\jvmTest\\");
Class<?> clazz = loader1.loadClass("com.jvm.t1.MyTest15");
System.out.println("class:"+ clazz.hashCode());
Object object = clazz.newInstance();
System.out.println(object); // loader1 指向新的实例
loader1 = new MyTest16("loader1");
//此路径为classPath,故 findClass方法不会被调用执行! 如果换个路径,不是classPath就会去执行了!
loader1.setPath("D:\\eclipse_pj\\dianshang\\jvmTest\\out\\production\\jvmTest\\");
//指向新的
clazz = loader1.loadClass("com.jvm.t1.MyTest15");
System.out.println("class:"+ clazz.hashCode());
// 指向新的
object = clazz.newInstance();
System.out.println(object); }
}

调用:

public class Test17 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
MyTest16 loader1 = new MyTest16("loader1");
loader1.setPath("D:\\test\\jvm\\"); Class<?> clazz = loader1.loadClass("com.jvm.t1.test");
System.out.println("class"+ clazz.hashCode()); Object o = clazz.newInstance();
}
}

写一个自定义类加载器demo的更多相关文章

  1. Java内存管理-掌握自定义类加载器的实现(七)

    勿在流沙筑高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 上一篇分析了ClassLoader的类加载相关的核心源码,也简单介绍了ClassLoa ...

  2. 4.自定义类加载器实现及在tomcat中的应用

    了解了类加载器的双亲委派机制, 也知道了双亲委派机制的原理,接下来就是检验我们学习是否扎实了,来自定义一个类加载器 一. 回顾类加载器的原理 还是这张图,类加载器的入口是c++调用java代码创建了J ...

  3. 手写一个类加载器demo

    1.什么是类加载器? 2.加载方式 ClassLoader类加载器,主要的作用是将class文件加载到jvm虚拟机中.jvm启动的时候,并不是一次性加载所有的类,而是根据需要动态去加载类,主要分为隐式 ...

  4. java类加载器学习2——自定义类加载器和父类委托机制带来的问题

    一.自定义类加载器的一般步骤 Java的类加载器自从JDK1.2开始便引入了一条机制叫做父类委托机制.一个类需要被加载的时候,JVM先会调用他的父类加载器进行加载,父类调用父类的父类,一直到顶级类加载 ...

  5. Java自定义类加载器与双亲委派模型

    其实,双亲委派模型并不复杂.自定义类加载器也不难!随便从网上搜一下就能搜出一大把结果,然后copy一下就能用.但是,如果每次想自定义类加载器就必须搜一遍别人的文章,然后复制,这样显然不行.可是自定义类 ...

  6. (转)JVM——自定义类加载器

    背景:为什么要自定义,如何自定义,实现过程 转载:http://blog.csdn.net/SEU_Calvin/article/details/52315125 0. 为什么需要自定义类加载器 网上 ...

  7. JVM自定义类加载器加载指定classPath下的所有class及jar

    一.JVM中的类加载器类型 从Java虚拟机的角度讲,只有两种不同的类加载器:启动类加载器和其他类加载器. 1.启动类加载器(Boostrap ClassLoader):这个是由c++实现的,主要负责 ...

  8. jvm(1)类的加载(二)(自定义类加载器)

    [深入Java虚拟机]之四:类加载机制 1,从Java虚拟机的角度,只存在两种不同的类加载器: 1,启动类加载器:它使用C++实现(这里仅限于Hotspot,也就是JDK1.5之后默认的虚拟机,有其他 ...

  9. JVM——自定义类加载器

    )以上两种情况在实际中的综合运用:比如你的应用需要通过网络来传输 Java 类的字节码,为了安全性,这些字节码经过了加密处理.这个时候你就需要自定义类加载器来从某个网络地址上读取加密后的字节代码,接着 ...

随机推荐

  1. leetcode-15双周赛-1287-有序数组中出现次数超过25%的元素

    题目描述: 方法一:二分法 class Solution: def findSpecialInteger(self, arr: List[int]) -> int: span = len(arr ...

  2. 微信小程序中显示html富文本的方法

    微信小程序中显示html富文本的方法 使用方法:git地址:https://github.com/icindy/wxParse 一.下载wxParse文件 二.在要引入的页面的js文件中,引入文件 j ...

  3. C/C++ 多线程注意事项

    { 1 父线程和子线程中的内存区是不一样的,如果涉及到堆内存应该注意,否则内存异常比无法解析的外部符号还要恐怖 }

  4. Delphi Win API 函数 [ ShellAPI ] ShellExecute 函数

    引用单元:uses ShellAPI; 函数原型:function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,Directory ...

  5. 学习总结-Redis

    一,简介 redis(Remote Dictionary Server)是一种Nosql技术,它是一个开源的高级kv存储和数据结构存储系统,它经常被拿来和Memcached相比较,但是Memcache ...

  6. .NET Core 通过 Ef Core 操作 Mysql

    1.运行环境 开发工具:Visual Studio 2017 JDK版本:.NET Core 2.0 项目管理工具:nuget 2.GITHUB地址 https://github.com/nbfujx ...

  7. node连接mysql数据库

    1. 创建项目,安装mysql 创建项目文件夹test, 在test文件夹下yarn add mysql --save安装mysql: 2. node使用mysql 在test文件夹下,创建test. ...

  8. php使用curl实现get和post请求的方法,数据传输urldecode和json

    PHP支持CURL库,利用URL语法规定来传输文件和数据的工具,支持很多协议,包括HTTP.FTP.TELNET等. 优点:是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS.CURL ...

  9. (67) c# 序列化

    二进制序列化器 xml序列化器 数据契约序列化器

  10. 每天一个linux常用命令--ls 和 -ll 有什么区别?

    一.-ls 和 -ll  有什么区别? 1. ls 命令可以说是linux下最常用的命令之一.ll不是命令,是ls -l的别名相当于windows里的快捷方式.所以"ll"和“ls ...