通过继承classloader实现自定义的类加载
package week01;
import java.io.*;
import java.util.Arrays;
public class MyClassLoader extends ClassLoader {
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
// 加载D盘根目录下指定类名的class
String clzDir = "D:\\" + File.separatorChar
+ name.replace('.', File.separatorChar) + ".xlass";
byte[] classData = getClassData(clzDir);
if (classData == null) {
throw new ClassNotFoundException();
} else {
return defineClass(name, classData, 0, classData.length);
}
}
获取文件class的byte数组
private byte[] getClassData(String path) {
try (InputStream ins = new FileInputStream(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream()
) {
int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
int bytesNumRead = 0;
while ((bytesNumRead = ins.read(buffer)) != -1) {
baos.write(buffer, 0, bytesNumRead);
}
return decode(baos.toByteArray());
//return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// 我在这里使用的是文件内容是一个 Hello.class 文件所有字节(x=255-x)处理后的文件 所以我这对文件进行了一个解密的操作
//解密
private byte[] decode(byte[] a) {
byte[] bytes = new byte[a.length];
for (int i = 0; i < a.length; i++) {
bytes[i] = (byte) (255 - a[i]);
}
return bytes;
}
}
通过反射调用class文件中的方法
public class MyClassLoaderTest {
public static void main(String[] args) throws Exception {
// 指定类加载器加载调用
// week01.MyClassLoader classLoader = new week01.MyClassLoader();
//System.out.println(classLoader.findClass("Hello"));
//classLoader.loadClass("Hello").getMethod("hello").invoke(null);
MyClassLoader mcl = new MyClassLoader();
Class<?> c1 = Class.forName("Hello", true, mcl);
Object obj = c1.newInstance();
Method method = obj.getClass().getMethod("hello");
String str = (String) method.invoke(obj);
}
}
执行这个main方法
可以看到我们在hello类中的打印的一句话