自定义类加载器其实就是通过继承classLoader类,并重写findClass方法来实现自定义类加载器的效果
import java.io.*; /** * 简单文件系统类加载器 * 通过输入类的全限定名在指定文件路径下加载class */ public class FileSystemClassLoader extends ClassLoader { private String root; public FileSystemClassLoader(String root) { this.root = root; } /** * 重写findClass 依然使用双亲委派机制 * @param name * @return * @throws ClassNotFoundException */ @Override protected Class<?> findClass(String name) throws ClassNotFoundException { Class<?> c = findLoadedClass(name); if (c != null) { return c; } else { try { ClassLoader parent = this.getParent(); c = parent.loadClass(name); System.out.println(name); }catch (Exception e){ } if (c != null) { System.out.println("Hello"); return c; } else { byte[] data = getClassName(name); if (data == null) { throw new ClassNotFoundException(); } else { c = defineClass(name, data, 0, data.length); } } } return c; } /** * 通过类名获取到类的绝对路径名称 * class文件写入byte[]数据中 * @param name * @return */ private byte[] getClassName(String name) { String path = root + "/" + name.replace(".", "/") + ".class"; System.out.println(path); InputStream is = null; ByteArrayOutputStream byos = new ByteArrayOutputStream(); try { is = new FileInputStream(path); int len = 0; byte[] buffer = new byte[1024]; while((len = is.read(buffer))!=-1){ byos.write(buffer,0,len); } return byos.toByteArray(); } catch (IOException e) { e.printStackTrace(); return null; }finally { if(is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
public static void main(String[] args) { FileSystemClassLoader fs = new FileSystemClassLoader("C:/Users/Administrator/Desktop/temp"); try { Class<?> c = fs.findClass("com.smy.HelloWorld"); Class c1 = fs.findClass("java.lang.String"); System.out.println(c); System.out.println(c.getClassLoader()); System.out.println(c1.getClassLoader()); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
输入结果
class com.smy.HelloWorld reflect.FileSystemClassLoader@1540e19d null