自定义加载器只需要继承 java.lang.ClassLoader 有两种核心方法,一种是loadClasss(String, boolean),另一种实现父母分配机制的方法是findClass,默认实现是空的,所以我们自定义的加载器主要是重写findClass方法。
public class MyClassLoaderTest { static class TestClassLoader extends ClassLoader { private String classPath; public TestClassLoader(String classPath) { this.classPath = classPath; } private byte[] loadByte(String name) throws Exception { name = name.replaceAll("\\.", "/"); FileInputStream fis = new FileInputStream(classPath + "/" + name + ".class"); int len = fis.available(); byte[] data = new byte[len]; fis.read(data); fis.close(); return data; } protected Class<?> findClass(String name) throws ClassNotFoundException { try { byte[] data = loadByte(name); return defineClass(name, data, 0, data.length); } catch (Exception e) { e.printStackTrace(); throw new ClassNotFoundException(); } } protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class<?> c = findLoadedClass(name); if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); if (!name.startsWith("org.example")) { c = getParent().loadClass(name); } else { c = findClass(name); } // this is the defining class loader; record the stats sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } if (resolve) { resolveClass(c); } return c; } } } public static void main(String args[]) throws Exception { TestClassLoader classLoader = new TestClassLoader("F:/test"); Class clazz = classLoader.loadClass("org.example.Test"); Object obj = clazz.newInstance(); Method method = clazz.getDeclaredMethod("test", null); Object invoke = method.invoke(obj, null); System.out.println("=====" + invoke); System.out.println(clazz.getClassLoader().getClass().getName()); }}
