一,如何自定义classLoader?
需要使用加载器的loadClass方法:ClassLoader().loadClass
查看loadClass方法源码
首先检查加载,调用父5加载器开始双亲委派机制,
如果没有加载到,就调用findClass方式
打开发现是抛出了异常,那么如何自定义自己的类加载器,就只能重写这个方法来完成。
我们知道ClassLoader是所有加载器的父类,根据
Launcher找到ExtClassLoader ,然后根据继承关系找到直接ClassLoader的子类SecureClassLoader ,查看其findClass方法实现;但由于SecureClassLoader没有对findClass实现,最后发现在URLClassLoader 中找到了对应的实现。
1,找到对应的文件,转为二进制流;
2,交给父类的defineClass加载到内存中;
二,自定义ClassLoader
1,准备一个被加载的类
放在非项目下,我的是在D盘下
新建一个HelloWorld.txt
以utf-8无BOM格式转为.JAVA文件,使用 javac编译城class
2,自定义ClassLoader并findClass方法
package com.example.demo.jvm.classLoader;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;public class Test2_MyClassLoad extends ClassLoader {public static void main(String argv[]) throws ClassNotFoundException, IllegalAccessException, InstantiationException {Test2_MyClassLoad test2_myClassLoad = new Test2_MyClassLoad();Class<?> c = test2_myClassLoad.loadClass("HelloWorld");//输出HelloWorld的加载器System.out.println(c.newInstance().getClass().getClassLoader());//输出自定义加载器的加载器System.out.println(test2_myClassLoad.getClass().getClassLoader());}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {try {byte[] bytes = loadByte("D:/".concat(name).concat(".class"));return defineClass(name,bytes,0,bytes.length);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return super.findClass(name);}private byte[] loadByte(String path) throws IOException {File file = new File(path);FileInputStream fi = new FileInputStream(file);int len = fi.available();byte[] b = new byte[len];fi.read(b);return b;}}
console:
Hello World !
com.example.demo.jvm.classLoader.Test2_MyClassLoad@19469ea2
sun.misc.Launcher$AppClassLoader@18b4aac2