Java 是否可以在不启动新VM的情况下修改类加载器行为?

Java 是否可以在不启动新VM的情况下修改类加载器行为?,java,classloader,abstract-syntax-tree,Java,Classloader,Abstract Syntax Tree,使用注释处理器测试AST转换和源代码生成的结果,我有一个类加载器,可以加载已编译(修改)的在我使用google的编译测试运行单元测试之后,将类转换为类并实例化它们,这样我还可以在实例化时对生成/类修改的行为进行单元测试。这是我的类加载器: public ClassLoader createClassLoader(com.google.testing.compile.Compilation compilation) throws InstantiationException

使用注释处理器测试AST转换和源代码生成的结果,我有一个类加载器,可以加载已编译(修改)的在我使用google的编译测试运行单元测试之后,将类转换为类并实例化它们,这样我还可以在实例化时对生成/类修改的行为进行单元测试。这是我的类加载器:

public ClassLoader createClassLoader(com.google.testing.compile.Compilation compilation)
            throws InstantiationException,
            IllegalAccessException,
            ClassNotFoundException,
            IOException, NoSuchFieldException {

    return new ClassLoader() {

        final List<JavaFileObject> files = getFiles(compilation);

        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            System.out.println("Loading compiled class: " + name);

            JavaFileObject mc = this.getFileFromName(name, files);

            if (mc != null) {

                try {

                    byte[] bytes = new byte[5000];

                    int len = mc.openInputStream().read(bytes);
                    files.remove(mc);

                    return defineClass(name, bytes, 0, len);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return super.findClass(name);
        }

        private JavaFileObject getFileFromName(String name,
                                               List<JavaFileObject> input) {
            return input.stream().filter(object -> {
                final URI normalize = object.toUri().normalize();
                String curr = normalize.toString();
                curr = curr.substring(("mem:///CLASS_OUTPUT/").length(),
                        curr.length() - ".class".length());
                curr = curr.replace("/", ".");
                return Objects.equals(curr, name);
            }).findAny().orElse(null);
        }
    };
我希望能够修改现有的类,以便可以运行编译任务,并让它识别在使用“-printsource”参数等运行编译测试时动态加载的类


它是用于单元测试的,所以反射/插装很好,想知道是否有一种简单的方法可以用当前的类加载器加载类或者替换它

要重新加载更新的类,您通常会丢弃类加载器并创建一个新的类加载器。如果类加载器加载的代码没有内存泄漏,垃圾收集器将释放旧类加载器及其加载的类的内存。@Andreas我的编译器插件先编译,然后编译技术上甚至在初始编译中都不存在的原始源代码-我的处理器内置在测试类路径上的一个jar中&测试类位于类路径外的一个resources文件夹中。我试图模拟其他源代码的编译,也试图一次性测试结果,所以我猜它没有更新类,因为它们在测试之前不存在compilation@Andreas只是当使用类似“printsource”的代码运行测试时,它无法找到编译后的类,并抛出“未找到类”错误
ClassLoader loader = (new CompilerUtil().createClassLoader(compilation));
Class clazz = loader.loadClass(fullName);
Object instance = clazz.newInstance();