【亿码酷站-编程开发教程】收集全网优质教程及源码资源!

全网优质软件开发、平面设计等教程及精品源码资源一站可得,www.ymkuzhan.com!

java实现自定义类加载器_亿码酷站_亿码酷站插图

类加载器虽然以父子相称,但是没有继承关系

(视频教程推荐:java课程

点入ClassLoader的源码查看样例:

* <blockquote><pre>
 *     class NetworkClassLoader extends ClassLoader {
 *         String host;
 *         int port;
 *
 *         public Class findClass(String name) {
 *             byte[] b = loadClassData(name);
 *             return defineClass(name, b, 0, b.length);
 *         }
 *
 *         private byte[] loadClassData(String name) {
 *             // load the class data from the connection
 *             &nbsp;.&nbsp;.&nbsp;.
 *         }
 *     }
 * </pre></blockquote>

只需继承CalssLoader,重写 findClass方法即可:

package reflect;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
 
public class MyClassLoader extends ClassLoader{
 
    // 用于保存加载的文件的大小
    private int classSize; 
    // 新增的类加载路径
    private static List<String> paths = new ArrayList<>();
 
    static {
        paths.add("D:\\Users\\jeff.chan\\Desktop\\");
    }
    // 默认会将app类加载器做为该类加载器的父加载器
    public MyClassLoader() {
    }
 
    public MyClassLoader(ClassLoader parent) {
        super(parent);
    }
 
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] b = loadBinaryData(name);
        // 打印执行标记
        System.out.println("use custom classloader...");
        return defineClass(name, b,0, classSize);
    }
 
    public byte[] loadBinaryData(String name) throws ClassNotFoundException{
        String pathName = name.replaceAll("\\.", "/");
        File file = null;
        for (String path : paths) {
            file = new File(path+pathName+".class");
            if(file.exists() && file.isFile()){
                break;
            }
        }
        if(file==null || !file.isFile()){
            throw  new ClassNotFoundException();
        }
        // 读取文件的二进制信息
        try (InputStream in = new FileInputStream(file)){
            // 一般这个大小够了,这里是为了方便读取
            // 文件的内容,所以一次性读入,并且将大小返回
            // 用于defineClass
            byte[] b = new byte[1024 * 1024 * 10];
            classSize = in.read(b);
            return b;
        }catch (IOException ioException){
            ;
        }
        return null;
    }
}

这里加入了一个MyClassLoader自定义类加载器,扫描的路径为:

D:\\Users\\jeff.chan\\Desktop\\

那么新加入的类加载器就和app类加载器,扩展类加载器,启动类加载器一起起作用。

测试用例:

package reflect;
 
 
public class Person {
 
    private String name;
    private String age;
 
    public Person() {
    }
 
    public Person(String name, String age) {
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getAge() {
        return age;
    }
 
    public void setAge(String age) {
        this.age = age;
    }
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

客户端:

package reflect;
 
public class Client {
 
    public static void main(String[] args) throws Exception {
        MyClassLoader classLoader = new MyClassLoader();
        Class<?> aClass = classLoader.loadClass("reflect.Person");
        System.out.println(aClass);
        System.out.println(aClass.getClassLoader());
    }
}

时直接运行代码:那么会输出

class reflect.Person
sun.misc.Launcher$AppClassLoader@18b4aac2

发现自己的类加载器根本不起作用。其实是因为双亲委托机制:

1、MyClassLoader 查看是否已经加载 -》 2、App类加载查看是否已经加载 -》3、 扩展类加载器查看是否已经加载

-》 4、启动类加载器查看是否已经加载,没有加载就尝试加载 -》 5、扩展类尝试加载 -》 6、app类加载尝试加载 -》 7、MyClassLoader尝试加载 -》 8、抛出找不到类的异常

上述的流程中,第6步会找到对应的类,所以就直接返回了,根本没有给MyClassLoader机会加载,所以才没有调用自定义的类加载器MyClassLoader。

如果想要加载的话,那么就到编译生成的Person.class移动到桌面reflect/Person.class下,执行结果:

use custom classloader…
class reflect.Person
reflect.MyClassLoader@135fbaa4

结果发现,自定义的类加载起作用了,其实就是上述的流程中的第7步,找到了相应的类的二进制文件,加载了进来。

相关推荐:java入门

java实现自定义类加载器
—–文章转载自PHP中文网如有侵权请联系admin#tyuanma.cn删除

mysql语句中like用法是什么

下载声明:
  • 本站资源如无特殊说明默认解压密码为www.ymkuzhan.com建议使用WinRAR解压;
  • 本站资源来源于用户分享、互换、购买以及网络收集等渠道,本站不提供任何技术服务及有偿服务,资源仅提供给大家学习研究请勿作它用。
  • 赞助本站仅为维持服务器日常运行并非购买程序及源码费用因此不提供任何技术支持,如果你喜欢该程序,请购买正版!
  • 版权声明:
  • 下载本站资源学习研究的默认同意本站【版权声明】若本站提供的资源侵犯到你的权益,请提交版权证明文件至邮箱ymkuzhan#126.com(将#替换为@)站长将会在三个工作日内为您删除。
  • 免责声明:
  • 您好,本站所有资源(包括但不限于:源码、素材、工具、字体、图像、模板等)均为用户分享、互换、购买以及网络收集而来,并未取得原始权利人授权,因此禁止一切商用行为,仅可用于个人研究学习使用。请务必于下载后24小时内彻底删除,一切因下载人使用所引起的法律相关责任,包括但不限于:侵权,索赔,法律责任,刑事责任等相关责任,全部由下载人/使用人,全部承担。以上说明,一经发布视为您已全部阅读,理解、同意以上内容,如对以上内容持有异议,请勿下载,谢谢配合!支持正版,人人有责,如不慎对您的合法权益构成侵犯,请联系我们对相应内容进行删除,谢谢!