• 自定义类加载器(一)


    示例代码

    1、首先建一个类Test.java(放在comdemo cpkakaclassloader目录下,编译生成Test.class)

    public class Test {
        private String a;
        public Test(){
    
        }
        public Test(String a){
            this.a=a;
        }
        public static void main(String[] args) {
             System.out.println("aaaaaaaaaa");
        }
    }
    

    2、自定义类加载器MyClassLoader.java

    public class MyClassLoader  extends ClassLoader{
        @Override
        protected Class<?> findClass(String name) {
            byte[] bytes=null;
            //将点替换成斜杠
            String fileName=name.replaceAll("\.","/");
            StringBuilder sb=new StringBuilder("C:\Users\Administrator\Desktop\");
            sb.append(fileName);
            sb.append(".class");
            fileName=sb.toString();
            try {
                InputStream is=new FileInputStream(fileName);
                ByteArrayOutputStream bos=new ByteArrayOutputStream();
                byte[] buf=new byte[1024];
                int r=0;
                while ((r=is.read(buf))!=-1){
                    bos.write(buf,0,r);
                }
                bytes=bos.toByteArray();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return defineClass(name,bytes,0,bytes.length);
        }
    
        public static void main(String[] args) throws Exception{
            //自定义类加载器对象1
            MyClassLoader c1=new MyClassLoader();
            String className="com.demo.tcp.kaka.classloader.Test";//loadClass调用的就是findClass()
            Class clazz1=c1.loadClass(className);
    
            //自定义类加载器对象2
            MyClassLoader c2=new MyClassLoader();
            Class clazz2=c2.loadClass(className);
    
            System.out.println(clazz1.getClassLoader());
            System.out.println(clazz2.getClassLoader());
    
            if(clazz1!=clazz2){
                System.out.println("不同的类加载器对象加载相同的class文件,会产生不同的类对象");
            }
            Object obj1=clazz1.getDeclaredConstructor(new Class[]{String.class}).newInstance("自定义加载器加载进内存的");
            Field fa=clazz1.getDeclaredField("a");
            fa.setAccessible(true);//将私有变量设置成可以访问的权限
            System.out.println(fa.get(obj1));
        }
    

    执行结果

    com.demo.tcp.kaka.classloader.MyClassLoader@15db9742
    com.demo.tcp.kaka.classloader.MyClassLoader@7852e922
    不同的类加载器对象加载相同的class文件,会产生不同的类对象
    自定义加载器加载进内存的
    

    注意事项

    • 如果将Test.java文件拷贝到idea编辑器中,那么MyClassLoader中的findClass就不会执行了,所以需要复制到外边;因为c1和c2都继承自ClassLoader,所以直接交给上级类加载器加载应用程序类加载器:AppClassLoader;它会首先找到Test.class文件,并加入内存;此时就不会在继续再向下传播调用加载了,因此MyClassLoader不会被调用。
    • 类加载器在加载的时候虚拟机会首先调用加载器的私用方法loadClassInternal()而这个方法唯一作用就是调用自己的loadClass()方法,如果loadClass()加载失败了,则会调用自己的findClass()。当然loadClass()也能被重写,但是我们不会这样做,因为这样做的话,所有的类都会走这个方法来加载类;那么虚拟机内置的一些类也会用这个方法里面的逻辑来加载,固定会报错。

    截图展示

    image


    image

  • 相关阅读:
    设计模式学习笔记(1)——简单工厂模式
    BarTender怎样同时打印自动日期和流水号?
    BarTender安装常见问题集结
    Windows更新导致的打印问题
    BarTender中如何为称重设备设置秤显示?
    BarTender中如何调整数据输入表单的大小?
    BarTender 2016如何导出模板为pdf文件?
    ABBYY PDF Transformer+安装教程
    ABBYY PDF Transformer+ 给你好看
    ABBYY PDF Transformer+功能概述
  • 原文地址:https://www.cnblogs.com/kaka-qiqi/p/14527056.html
Copyright © 2020-2023  润新知