gpt4 book ai didi

java - 为什么我的类没有重新加载?

转载 作者:行者123 更新时间:2023-12-02 08:35:26 26 4
gpt4 key购买 nike

我知道我错过了一些基本的东西。我正在尝试动态编译一个类,然后在更改后重新加载它。以下代码有效。但是,当我调用它两次(一次在更改 .java 之后)时,类定义不会更新。我错过了什么?

File file = new File("/eraseme/Eraseme.java");
File[] files = new File[] {file};
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(files);
CompilationTask task = compiler.getTask(null, fileManager, null, null,null,compilationUnits);
boolean madeIt = task.call(); // works

File classFile = new File("/eraseme/Eraseme.class");
URL url = classFile.toURL();
URL[] urls = new URL[] { url };
ClassLoader cl = new URLClassLoader(urls);
Class cls = cl.loadClass("Eraseme");
TestApi test = (TestApi) cls.newInstance();
System.out.println(test.getVersion());

最佳答案

您缺少的是传递给 URLClassLoader 的 url 应该是随后搜索的目录。发生的情况是,您正在构造的 URLClassLoader 实际上并未找到 .class 文件,而是无法找到该类,并且会回退到让父类加载器加载该类。

具体来说,尝试将代码的第二位修改为:

File classFile = new File("/eraseme");
URL url = classFile.toURL();
URL[] urls = new URL[] { url };
ClassLoader cl = new URLClassLoader(urls);
Class cls = cl.loadClass("Eraseme"); // will try to load /eraseme/Eraseme.class
TestApi test = (TestApi) cls.newInstance();
System.out.println(test.getVersion());

请注意,如果您的类被调用(使用包)com.mycompany.erasestuff.EraseMe,那么类加载器将在文件 /eraseme/com/mycompany/erasestuff/中查​​找EraseMe.class

请注意,当您执行此操作时,您不希望系统类加载器能够加载 EraseMe 类。系统类加载器将优先,您的 URLClassloader 将不会加载任何内容。 (不幸的是,当你对类加载器说“加载这个类”时,它首先检查其父类加载器是否可以加载该类,然后它会尝试自己加载它。如果系统类加载器可以加载这个类,你将永远不会得到不同的版本)

关于java - 为什么我的类没有重新加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1961686/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com