java类加载器分四大类:根加载器、扩展类加载器、系统类加载器以及自定义加载器。
自定义加载器,需要extends ClassLoader
1 public class CustomClassLoader extends ClassLoader{ 2 3 @Override 4 protected Class<?> findClass(String name) throws ClassNotFoundException { 5 byte[] data = loadClassData(name); 6 return super.defineClass(name,data,0,data.length); 7 } 8 9 private byte[] loadClassData(String className) { 10 className = className.replace(".", File.separator); 11 InputStream inputStream = null; 12 byte[] data = null; 13 try { 14 inputStream = new FileInputStream(new File(className+".class")); 15 data = IOUtils.toByteArray(inputStream); 16 } catch (Exception e){ 17 e.printStackTrace(); 18 } finally { 19 try { 20 inputStream.close(); 21 }catch (Exception e){ 22 e.printStackTrace(); 23 } 24 } 25 return data; 26 } 27 28 public static void main(String[] args) throws Exception{ 29 CustomClassLoader classLoader = new CustomClassLoader(); 30 Class<?> clazz = classLoader.loadClass("com.jvm.classloader.TestDemo"); 31 Object object = clazz.newInstance(); 32 System.out.println(object); 33
34 } 35 }
findClass(String):通过二进制名称来查找class。这个方法应该遵循类加载器的委托模型的类加载器来实现覆盖(重写该方法),并且将由loadClass方法在检查父类加载器以获取所请求的类之后调用。此方法由系统内部调用,而非代码主动调用。
loadClass(String): 加载指定的二进制文件名的class,执行的顺序:
1、调用findLoadedClass(String),查找是否已经加载 过,如果是则直接返回。
2、调用父类加载器的loadClass(String) ,如果父类是null,则使用VM内置加载器
3、调用findClass(String)查找class