我有这样的事情:
public static final String path;
static {
path = loadProperties("config.conf").getProperty("path");
}
public static void main(String... args) {
// ... do stuff (starting threads that reads the final path variable)
// someone want's to update the path (in the config.conf file)
restart(); // ???
}
我想重新初始化JVM再次调用静态初始化程序,然后再main(...)
!
可以吗?
答案 0 :(得分:3)
您可以使用自定义类加载器启动应用程序,这将允许您加载和卸载静态变量。
然而,基本上它是一个非常糟糕的设计需要这样做。我喜欢让田野最终,但如果你想改变它们,你不应该把它们作为最终。
答案 1 :(得分:2)
如果您的目标只是重新加载某些配置文件,为什么不实施文件更改监视器?
这是一个关于这个主题的好教程:
http://download.oracle.com/javase/tutorial/essential/io/notification.html
我认为你提出的建议(自动重启你的应用程序)比看文件更新要麻烦一些。
答案 2 :(得分:2)
我接受了Peter Lawrey回答,但发布了一个完整的例子供任何人使用!
我不会在生产代码中使用它......还有其他方法可以做到这一点!
public class Test {
public static void main(String args[]) throws Exception {
start();
Thread.sleep(123);
start();
}
private static void start() throws Exception {
ClassLoader cl = new ClassLoader(null) {
protected java.lang.Class<?> findClass(String name)
throws ClassNotFoundException {
try{
String c = name.replace('.', File.separatorChar) +".class";
URL u = ClassLoader.getSystemResource(c);
String classPath = ((String) u.getFile()).substring(1);
File f = new File(classPath);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte buff[] = new byte[(int) f.length()];
dis.readFully(buff);
dis.close();
return defineClass(name, buff, 0, buff.length, null);
} catch(Exception e){
throw new ClassNotFoundException(e.getMessage(), e);
}
}
};
Class<?> t = cl.loadClass("Test$Restartable");
Object[] args = new Object[] { new String[0] };
t.getMethod("main", new String[0].getClass()).invoke(null, args);
}
public static class Restartable {
private static final long argument = System.currentTimeMillis();
public static void main(String args[]) throws Exception {
System.out.println(argument);
}
}
}
答案 3 :(得分:1)
更简单的方法是不为此使用静态初始化程序。为什么不让path
非最终版并将其加载到main
?
答案 4 :(得分:0)
这个结构怎么样
public static void main(String... args) {
boolean restart = true;
while (restart )
{
retart = runApplication();
}
}
如果您发现需要重新启动应用程序,请让runApplication返回true。 如果是时候退出返回false;
答案 5 :(得分:0)
如果你有一个UI或一个守护进程,所以你可以控制输出到stdout,你可以在外面创建一个启动程序的包装器。
如果程序在退出时输出“RESTART”,则可以从此包装器重新启动程序。如果没有,它就结束了。
或者如果你想要纯粹的java方式,你可以像Peter Laurerey在帖子中提到的那样使用类加载器的解决方案。在沿着这条路走下去之前,你应该重新考虑你的设计(如果它是你的代码)并使你的代码能够清理自己。