参考:
一篇文章读懂Java类加载器
全面解析Java类加载器
类加载器
-
类加载器结构:
-
ClassLoader类是一个抽象类,但却没有包含任何抽象方法。
-
如果要实现自己的类加载器且不破坏双亲委派模型,只需要继承ClassLoader类并重写findClass方法。
-
如果要实现自己的类加载器且破坏双亲委派模型,则需要继承ClassLoader类并重写loadClass,findClass方法。
自定义类加载器
- 实现自定义类加载器的三步:
1.继承ClassLoader
2.重写findClass()方法
3.调用defineClass()方法
一个基本的自定义类加载器代码如下:
/*
* John Han.
* Copyright (c) 2019-2019 All Rights Reserved.
*/
package com.john.learn.basic.class_loader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
/*
* 自定义类加载器
* author: john.
* version: CustomClassLoader.java, v 0.1 2019年05月18日 下午5:14 Exp.
*/
public class CustomClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] result = getClassFromCustomPath(name);
if (result == null) {
throw new FileNotFoundException(name);
} else {
// defineClass方法将字节码转化为类
return defineClass(name, result, 0, result.length);
}
} catch (Exception e) {
e.printStackTrace();
}
throw new ClassNotFoundException(name);
}
private byte[] getClassFromCustomPath(String name) {
// 从自定义路径中加载指定类,返回类的字节码文件
InputStream in = null;
ByteArrayOutputStream out = null;
String path = "/Users/john/" + name + ".class";
try {
in = new FileInputStream(path);
out = new ByteArrayOutputStream();
byte[] buffer = new byte[2048];
int len = 0;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
return out.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
in.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
public static void main(String[] args) {
CustomClassLoader customClassLoader = new CustomClassLoader();
try {
Class<?> clazz = Class.forName("One", true, customClassLoader);
Object obj = clazz.newInstance();
// cn.xpleaf.coding.c4.CustomClassLoader@610455d6
System.out.println(obj.getClass().getClassLoader());
} catch (Exception e) {
e.printStackTrace();
}
}
}
网友评论