如何在Java中更改默认的类加载器?

前端之家收集整理的这篇文章主要介绍了如何在Java中更改默认的类加载器?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设我有三个类,例子ClassA,example.ClassB和example.ClassLoader. ClassA打印出HelloWorld和ClassB导入example.ClassA并调用其main()方法.如果我这样做:

java -cp Example.jar -Djava.system.class.loader=example.ClassLoader example.ClassA

它工作并使用我的类加载器.但是,如果我这样做:

java -cp Example.jar -Djava.system.class.loader=example.ClassLoader example.ClassB

ClassB使用我的类加载器,但ClassA(由ClassB导入)使用默认的类加载器加载.

有没有办法强制Java总是使用我的类加载器(除非另有一个类加载器被明确指定)?

编辑:感谢下面的PaŭloEbermann的回答,我发现问题是我调用父类加载器(URLClassLoader)加载我不需要触摸的类,而那些加载的类设置为上下文类加载器,所以从其导入的类使用我的自定义加载器的父类加载器. (令人困惑,抱歉)现在我可以通过手动阅读每个类来使其工作,但是看起来很多,因为我直接复制了URLClassLoader的代码.有没有办法告诉父类装载器来查找和定义类,但是将Class的上下文类加载器设置为您的自定义类加载器?

解决方法

如果您的类加载器正确实现,它将首先向其父类加载器询问应加载的任何类.

您的加载器的父类加载器可能是通常的应用程序类加载器.这意味着您的类加载器加载的每个类将首先在应用程序类加载器上搜索,并且只有在您找不到的时候才会搜索.

您的类加载器定义的所有类也将在类加载器上搜索所需的类.如果他们不这样做,你的ClassA并不是由你的装载机加载的.

如果这没有帮助,您需要显示一些有关如何获得结果的代码.

关于做什么的想法:

class ModifyingClassLoader extends URLClassLoader {

    // TODO: add constructors

    private boolean needsModifying(String name) {
        // TODO
    }

    private byte[] modifyClass(InputStream original) throws IOException {
        // TODO
    }

    public Class<?> findClass(String name) throws {
        if(needsModifying(name)) {
            try {
                InputStream classData = getResourceAsStream(name.replace('.','/') + ".class");
                if(classData == null) {
                    throw new ClassNotFoundException("class " + name + " is not findable");
                }
                byte[] array = modifyClass(classData);
                return defineClass(name,array,array.length);
            }
            catch(IOException io) {
                throw new ClassNotFoundException(io);
            }
        }
        else {
            return super.findClass(name);
        }
    }
}

对你的问题:

Is there a way to tell the parent class loader to find and define the class,
BUT set the Class’s context class loader to your custom one?

不,类的ClassLoader总是一个被调用来创建类的defineClass方法的类. (context class loader是别的 – 它是线程特定的,只有明确想要使用它的类才使用,而不是通过解析自己的直接依赖关系的类来使用).

原文链接:https://www.f2er.com/java/125139.html

猜你在找的Java相关文章