我最近发了一篇文章
Update Java code during runtime,经过几个小时摆弄不同的示例代码和阅读教程后,我遇到了以下问题:
通过使用ClassLoader,我可以在运行时使用http://www.exampledepot.com/egs/java.lang/reloadclass.html的代码将类MyVar1中的局部变量更改为类MyVar2,但是我无法用另一个版本的MyVar2替换该类MyVar2.
MyVar1和MyVar2都实现了一个接口VarInterface.主类使用VarInterface类型保存变量的实例.
我已经阅读了其他几个声称是正确的实现,但我无法使其工作.谁能看到我在这里做错了什么?
主类循环:
while(true){
i++;
Thread.sleep(1000);
ui.ping();
if(i > 3)
replaceVar();
}
replaceVar:
ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader();
MyClassLoader classLoader = new MyClassLoader(parentClassLoader);
Class newClass = classLoader.loadClass("MyVar2");
ui = (VarInterface)newClass.newInstance();
MyClassLoader.loadClass:
public Class> loadClass(String what){
// Get the directory (URL) of the reloadable class
URL[] urls = null;
try {
// Convert the file object to a URL
File dir = new File(System.getProperty("user.dir")
+File.separator+"dir"+File.separator);
URL url = dir.toURL();
urls = new URL[]{url};
} catch (MalformedURLException e) {
}
// Create a new class loader with the directory
ClassLoader cl = new URLClassLoader(urls);
// Load in the class
Class cls = null;
try {
cls = cl.loadClass("MyVar2");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return cls;
}
对于前3次迭代,MyVar1.ping()被调用,之后MyVar2.ping()被无限调用,即使我替换了MyVar2.class和MyVar2.java文件.
最佳答案 我猜你正在使用两个类加载器.一个是系统类加载器,其中包含大量代码.您的自定义类加载器使用系统类加载器作为其父级.您正在尝试使用自定义类加载器来替换系统类加载器中的类.实际上,自定义类加载器将优先委托给父类加载它自己的类.
您需要做的是确保系统类加载器不加载该类的实现.创建一个类加载器,用于加载类的实现并委托给系统类加载器.要更改实现,请创建类加载器的另一个实例.
(使用java.net.URLClassLoader.newInstance可能更容易创建自己的类加载器实现.)