请把小熊还给我& 2022-05-14 08:22 采纳率: 80%
浏览 37

java重写了类加载器不能通过new的方式创建对象了吗

自定义了类加载器为啥只能通过反射创建对象,想new就没有办法了吗

  • 写回答

1条回答 默认 最新

  • blackoon88 2022-05-14 17:17
    关注

    指定外部的class文件,只能通过反射创建对象;在破坏双亲委派原则的情况下,虽使用自定义的类加载器,但是你要使用类加载load然后创建对象。所以要使用自定义的类加载器就不能通过new的方式创建对象。

    参照代码如下:

    package com.demo1;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * @Author blackoon88
     * @Date 2022/5/14
     */
    
        public class MyClassLoader2 extends ClassLoader{
    
            public static void main(String[] args) throws Exception {
    
                /**
                 * 重写loadClass,违背了双亲委派原则。
                 * 因为双亲委派的逻辑是在loadClass中通过递归实现
                 * 正确操作为重写findClass
                 */
                ClassLoader load = new ClassLoader() {
                    @Override
                    public Class<?> loadClass(String name) throws ClassNotFoundException {
                        try {
                            String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
                            InputStream resourceAsStream = getClass().getResourceAsStream(fileName);
    
                            if (resourceAsStream == null) {
                                return super.loadClass(name);
                            }
                            byte[] b = new byte[resourceAsStream.available()];
                            resourceAsStream.read(b);
                            return defineClass(name, b, 0, b.length);
                        } catch (IOException e) {
                            throw new ClassNotFoundException();
                        }
                    }
                };
    
    
                ClassLoader find = new ClassLoader() {
                    @Override
                    protected Class<?> findClass(String name) throws ClassNotFoundException {
                        String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
                        InputStream resourceAsStream = getClass().getResourceAsStream(fileName);
                        if (resourceAsStream == null) {
                            return super.findClass(name);
                        } else {
                            byte[] b = new byte[0];
                            try {
                                b = new byte[resourceAsStream.available()];
                                resourceAsStream.read(b);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            return defineClass(name, b, 0, b.length);
                        }
                    }
                };
    
                // 重写loadClass,破坏双亲委派原则,但会使用自定义的类加载器
                Object loadObject = load.loadClass("com.demo1.MyClassLoader2").newInstance();
                System.out.println("load:"+ loadObject.getClass().getClassLoader());
                System.out.println(loadObject instanceof MyClassLoader2);
                System.out.println("------------------------------------------------------");
                // 重写findClass,运行时由于要加载的类在classpath下已经编译好,则会用AppClassLoader来加载,
                // 如果要使用自定义累加器的加载,则应该使用类路径classpath外的一个class文件,并且类路径下不能包含此class
                // 才能使用到自定义的类加载器
                Object findObject = find.loadClass("com.demo1.MyClassLoader2").newInstance();
                System.out.println("find:"+ findObject.getClass().getClassLoader());
                System.out.println(findObject instanceof MyClassLoader2);
            }
    
    
        }
    

    若有帮助,谢谢采纳~

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月14日

悬赏问题

  • ¥15 mmo能不能做客户端怪物
  • ¥15 osm下载到arcgis出错
  • ¥15 Dell g15 每次打开eiq portal后3分钟内自动退出
  • ¥200 使用python编写程序,采用socket方式获取网页实时刷新的数据,能定时print()出来就行。
  • ¥15 matlab如何根据图片中的公式绘制e和v的曲线图
  • ¥15 我想用Python(Django)+Vue搭建一个用户登录界面,但是在运行npm run serve时报错了如何解决?
  • ¥15 QQ邮箱过期怎么恢复?
  • ¥15 登录他人的vue项目显示服务器错误
  • ¥15 (标签-android|关键词-app)
  • ¥15 comsol仿真压阻传感器