一、方法1:
Class<?> java.lang.ClassLoader.loadClass(String s, boolean flag) throws ClassNotFoundException;
1、首先查询传入的S类是否已经被加载,如果加载就返回;
2、否则,查看当前类加载器是否有父类加载器,如果有父类,就一直调用父类的 此方法 加载该类,如此递归,一直到顶层的启动类加载器,尝试去加载该类。
3、如果父类加载器无法加载该类,调用自定义的 findClass(s)方法,获取该类。
二、方法2:
Class java.lang.ClassLoader.findClass(String s) throws ClassNotFoundException;
1、自定义的类加载器,需重写此方法,以保证所有的父类加载器不能加载给定的二进制名字的类的时候,调用此方法进行加载。
2、此方法中,首先需要通过IO读取给定的类,并返回一个二进制字节流数组(byte[]),然后,需调用 Native方法 defineClass(),将传入的二进制字节流转化为 Class对象。
如下代码:
@Override
protected Class<?> findClass(String className) throws ClassNotFoundException {
byte[] bytes = loadClassData(className); // 获取二进制字节流
return defineClass(className, bytes, 0, bytes.length);
}
三、方法3:
Class<?> java.lang.ClassLoader.defineClass(String s, byte[] abyte0, int i, int j) throws ClassFormatError;
1、将bytes[]数组转换为Class类的实例。
2、参数 String s:结果类的二进制类名
byte[] abyte0:类的二进制字节数组
int i:开始字节下标
int j:结束字节下标
四、方法4:
byte[] cn.com.ccxi.test.jvm.TestCode16_Revise.loadClassData(String className);
1、获取IO流,生成目标文件的二进制字节数组。
如下代码:
private byte[] loadClassData(String className) {
className = className.replace(".", "\\");
InputStream is = null;
byte[] bytes = null;
ByteArrayOutputStream baos = null;
try {
String path = rootPath + className + SUFFIX;
is = new FileInputStream(new File(path));
baos = new ByteArrayOutputStream();
int len;
while(-1 != (len = is.read())) {
baos.write(len);
}
bytes = baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
is.close();
baos.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return bytes;
}