双亲委派【java】

1、object 使用equals时会使用全限定名,其中classloader的名称会在object全限定名中

image.png

package cn.xx.user;

import cn.hutool.core.util.StrUtil;

import java.lang.reflect.Field;

public class test {
    public static void main(String[] args) throws Exception {
        String codePath="C:\\other\\project\\xx-recruit-api\\xx-user-api\\target\\classes\\";
        DiyClassLoader diyClassLoader=new DiyClassLoader(codePath);
        Class<?> aClass = diyClassLoader.loadClass("cn.xx.user.Student");
        Object o = aClass.newInstance();
        Field name = aClass.getDeclaredField("name");
        name.setAccessible(true);
        name.set(o,"小明");
        Field age = aClass.getDeclaredField("age");
        age.setAccessible(true);
        age.set(o,23);

        Student student = new Student("小明", 23);
        System.out.println(StrUtil.format("A对象{}",o));
        System.out.println(StrUtil.format("B对象{}",student));
        System.out.println(StrUtil.format("A equals B result:{}",o.equals(student)));
        System.out.printf("A对象的加载器:");
        System.out.println(o.getClass().getClassLoader());
        System.out.printf("B对象的加载器:");
        System.out.println(student.getClass().getClassLoader());
    }
}
package cn.xx.user;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author 2022-11-21 zfz
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private String name;
    private Integer age;
}

package cn.xx.user;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author 2022-11-21 zfz
 */
public class DiyClassLoader extends ClassLoader {
    private String codePath;

    public DiyClassLoader(ClassLoader parent, String codePath) {
        super(parent);
        this.codePath = codePath;
    }

    public DiyClassLoader(String codePath) {
        this.codePath = codePath;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        BufferedInputStream bis = null;
        ByteArrayOutputStream bos = null;
        codePath += name.replace('.', '/').concat(".class");
        byte[] bytes = new byte[1024];
        int line = 0;
        try {
            bis = new BufferedInputStream(new FileInputStream(codePath));
            bos = new ByteArrayOutputStream();
            while ((line = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, line);
            }
            bos.flush();
            bytes = bos.toByteArray();
            return defineClass(null, bytes, 0, bytes.length);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bis.close();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return super.findClass(name);
    }

    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t1 = System.nanoTime();
                //如果包名是com开头的,调用自定义类的findClass方法,否则调用父类的loadClass方法
                if (name.startsWith("cn")) {
                    c = this.findClass(name);
                } else {
                    c = this.getParent().loadClass(name);
                }
                sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                sun.misc.PerfCounter.getFindClasses().increment();
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
}

在线运行:
https://eaf93591.lightly.teamcode.com/

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值