自定义类加载器

package cn.dongqing.classloader;

import cn.dongqing.demo.entity.LongLong;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 * 自定义类加载器
 *
 * @date 2020/4/2
 */
public class MyClassLoader extends ClassLoader {

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] data = this.getData(name);
        return this.defineClass("cn.dongqing.demo.entity.LongLong", data, 0, data.length);
    }

    public static void main(String[] args) throws Exception {
        LongLong longLong = new LongLong();
        Class<? extends LongLong> aClass1 = longLong.getClass();
        System.out.println(aClass1.getClassLoader());
        MyClassLoader classLoader = new MyClassLoader();
        // 不会引起类初始化,不会运行静态代码块,可以看底层调用,resolve=false;
        Class<?> aClass = classLoader.findClass("F:\\dairy-queen\\target\\classes\\cn\\dongqing\\demo\\entity" +
            "\\LongLong.class");
        // 实例化首先要初始化类,所有会运行静态代码块
        Object o = aClass.newInstance();
        System.out.println(aClass.getClassLoader());
        Method doSomething = aClass.getMethod("doSomething", String.class);
        doSomething.invoke(o, "测试类加载器");
        // 不会引起类初始化,不会运行静态代码块,可以看底层调用,resolve=false;
        Class<?> aClass2 = classLoader.findClass("F:\\dairy-queen\\target\\classes\\cn\\dongqing\\demo\\entity" +
            "\\LongLong.class");
        System.out.println(aClass1 == aClass);
        System.out.println(aClass1);
        System.out.println(aClass);
        System.out.println(aClass2);
        System.out.println(aClass == aClass2);
    }

    private byte[] getData(String name) {

        File file = new File(name);
        if (file.exists()) {
            FileInputStream in = null;
            ByteArrayOutputStream out = null;
            try {
                in = new FileInputStream(file);
                out = new ByteArrayOutputStream();

                byte[] buffer = new byte[1024];
                int size = 0;
                while ((size = in.read(buffer)) != -1) {
                    out.write(buffer, 0, size);
                }

            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    in.close();
                } catch (IOException e) {

                    e.printStackTrace();
                }
            }
            return out.toByteArray();
        } else {
            return null;
        }


    }

}
同一个类,可以被不同类加载器加载,会导致堆中出现两个Class对象,如果类加载器继承了系统的三个类加载器,parent != null,则只会加载一次。
自定义来加载器加载同一个类,多次会抛出异常
Exception in thread "main" java.lang.LinkageError: loader (instance of  cn/dongqing/classloader/MyClassLoader): attempted  duplicate class definition for name: "cn/dongqing/demo/entity/LongLong"
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
	at cn.dongqing.classloader.MyClassLoader.findClass(MyClassLoader.java:22)
	at cn.dongqing.classloader.MyClassLoader.main(MyClassLoader.java:39)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值