程光CS 2023-03-08 21:01 采纳率: 50%
浏览 41

为什么自定义类加载器在第一次加载一个类时还会再加载java.lang.Object类

我在通过一个如下自定义类加载器的对象第一次加载一个类时,发现它在loadclass指定类后,还会再loadclass java.lang.Object类,我就感到非常疑惑,java.lang.Object类不是应该早就加载在jvm中了吗?并且我用这个自定义类加载器对象第二次加载类时,就不会再loadclass java.lang.Object类了,难道是对于每个加载器对象,都有一个结构来记录经过它loadclass的类吗,而不仅仅是像DIctionary结构一样只记录完全是由它加载的类。在jvm底层到底是如何查询判断一个类是否已经加载的呢?

    public static class HotClassLoader extends ClassLoader{

        public final static String classFilePath = "D:\\DownLoadProject\\LearnJVM\\out\\production\\LearnJVM\\"; //编译后classpath路径

        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            return loadClass(name, false);
        }

        /**
         * 重写loadClass方法,拦截指定类 不委托给父类加载器处理
         */
        @Override
        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{
            //注意:loadClass也会加载name类中引用到的相关的类,例如其父类Object,而Object类需要委托加载,故这里要加个判断
            if (name.startsWith("com.hotClass")) {
                synchronized (getClassLoadingLock(name)) {
                    //findLoadedClass:若存在name相同并且加载器实例对象相同的类对象 则将其返回,否则返回null
                    Class<?> c = findLoadedClass(name);
                    if (c == null) {
                        c = findClass(name);
                    }
                    if (resolve) {
                        resolveClass(c);
                    }
                    return c;
                }
            }
            return super.loadClass(name, resolve);
        }

        @Override
        protected Class<?> findClass(String classCompleteName) throws ClassNotFoundException {
            System.out.println("HotClassLoader尝试加载"+classCompleteName);
            byte[] result = getClassFromCustomPath(classFilePath +classCompleteName.replace(".", File.separator)+".class");
            if (result == null) {
                throw new ClassNotFoundException(classCompleteName);
            } else {
                return defineClass(classCompleteName, result, 0, result.length);
            }
        }

        private byte[] getClassFromCustomPath(String classFilePath) {
            File f = new File(classFilePath);
            InputStream is = null;
            try {
                //读取编译后的文件
                is = new FileInputStream(f);
                byte[] bytes=new byte[is.available()];
                is.read(bytes);
                return bytes;
            } catch (Exception e){

            } finally {
                try {
                    if (is != null) {
                        is.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }
  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-03-09 06:28
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 修改了问题 3月8日
  • 修改了问题 3月8日
  • 创建了问题 3月8日

悬赏问题

  • ¥15 is not in the mmseg::model registry。报错,模型注册表找不到自定义模块。
  • ¥15 安装quartus II18.1时弹出此error,怎么解决?
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音
  • ¥30 Pytorch深度学习服务器跑不通问题解决?
  • ¥15 部分客户订单定位有误的问题
  • ¥15 如何在maya程序中利用python编写领子和褶裥的模型的方法
  • ¥15 Bug traq 数据包 大概什么价
  • ¥15 在anaconda上pytorch和paddle paddle下载报错
  • ¥25 自动填写QQ腾讯文档收集表