自定义类加载器的一些问题

本文详细探讨了类加载器的工作原理,包括同一类文件被不同类加载器加载时Class对象的不相等特性,以及自定义类加载器加载类时其内部调用的其他类的加载过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、同一个类文件被不同类加载器加载,它们的Class对象不相等。

执行主类代码如下:


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;

/**
 * @Author 周利东
 * @Date: 2019/1/18 9:47
 */
public class ClassLoaderTest1 extends ClassLoader{
    public ClassLoaderTest1(){}
    public ClassLoaderTest1(ClassLoader parents){
        super(parents);
    }
    public static byte[] findClassBytes(String name) throws ClassNotFoundException {
        String url = "C:\\Users\\周利东\\Desktop\\" + name + ".class";
        File file = new File(url);
        try(FileInputStream fileInputStream = new FileInputStream(file)){
            byte[] bytes = new byte[1024];
            int readNum;
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            do{
                readNum = fileInputStream.read(bytes);
                if (readNum<=0) break;
                byteArrayOutputStream.write(bytes, 0, readNum);
            }while (readNum>0) ;
            return byteArrayOutputStream.toByteArray();
        }catch (Exception e){
            e.printStackTrace();
            throw new ClassNotFoundException("没找到文件");
        }
    }
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try{
            byte[] bytes = findClassBytes(name);
            return defineClass(name, bytes , 0, bytes.length);
        }catch (Exception e){
            e.printStackTrace();
            throw new ClassNotFoundException("没找到文件");
        }
    }
    public static void main(String[] args) throws Exception {
        ClassLoaderTest1 classLoaderTest1 = new ClassLoaderTest1(ClassLoader.getSystemClassLoader().getParent());
        ClassLoaderTest2 classLoaderTest2 = new ClassLoaderTest2(ClassLoader.getSystemClassLoader().getParent());
        Class<?> ttttttt1 = Class.forName("TTTTTTT", true, classLoaderTest1);
        Class<?> ttttttt2 = Class.forName("TTTTTTT", true, classLoaderTest2);
        System.out.println(ttttttt1.equals(ttttttt2));
        System.out.println("ttttttt1:classloader--"+ttttttt1.getClassLoader());
        System.out.println("ttttttt2:classloader--"+ttttttt2.getClassLoader());
        System.out.println(ttttttt1.newInstance().toString());
        System.out.println(ttttttt2.newInstance().toString());
    }
}


其中涉及到的两个class文件的java代码:(注意,这两个java要编译成class文件放到桌面,上面IO流的路径也可以自己更改)

/**
 * @Author 周利东
 * @Date: 2019/1/18 16:28
 */
public class TTTTTTT {
    private TTTTTTT(){}
    @Override
    public String toString() {
        return "classLoaderName=="+BeCaller.class.getClassLoader().toString()+"|||className=="+BeCaller.class.getName();
    }
}
/**
 * @Author 周利东
 * @Date: 2019/1/18 16:29
 */
public class BeCaller {
    private BeCaller(){}
}

做完上面的步骤之后,执行主类,输出结果为:

false
ttttttt1:classloader--ClassLoaderTest1@677327b6
ttttttt2:classloader--ClassLoaderTest2@7f31245a
classLoaderName==ClassLoaderTest1@677327b6|||className==BeCaller
classLoaderName==ClassLoaderTest2@7f31245a|||className==BeCaller

根据上面输出结果:

第一行可知:不同类加载器加载的同一个类的Class对象不相等。

第二、三行可知:ttttttt1和ttttttt2两个class对象 的确是由不同类加载器加载的

第四、五行可知:被TTTTTT类toString方法调用的BeCaller类,也分别由TTTTTT类所属的类加载器进行加载。即,一个类被某个类加载器加载,那么这个类所调用的所有类都会被这个类加载器加载。。

 

 

二、自定义类加载器所加载的类中 ,内部又调用了其他类,这些类由什么类加载器加载?

答:如果一个类被某个类加载器加载,那么该类内部调用了其他类的话,这些类默认也是由这个类加载器进行加载。。。除非内部又使用了其他类加载器。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值