2010-11-17 91 views
2

我有这样的事情:重新启动我自己 - 我可以从头开始重新初始化所有内容吗?

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

为什么不只是运行main(); – 2010-11-17 18:09:39

+0

我想他想要静态初始化块再次运行。它只在类加载时运行。 – shoebox639 2010-11-17 18:11:38

+0

难道你不能只是将静态块的主体放入主要方法吗?并只需调用main()? – shoebox639 2010-11-17 18:12:33

回答

3

您可以使用自定义类加载器启动您的应用程序,这将允许您加载和卸载您的静态变量。

但是,基本上它是一个非常糟糕的设计需要做到这一点。我喜欢最后决定场地,但如果你想改变它们,你不应该让它们成为最终的。

+1

用代码添加了一个答案,该代码显示了如何完成这个过程的例子! – dacwe 2010-11-18 10:56:46

1

一个简单的方法是简单的而不是为此使用静态初始值设定项。为什么不制造path非final并将其加载到main

2

如果您的目标只是重新加载一些配置文件,为什么不实施文件更改监视器?

下面是关于这个问题的一个很好的教程:

http://download.oracle.com/javase/tutorial/essential/io/notification.html

我认为你提出什么(自动重启你的应用程序)会比只是看文件的更新稍微繁琐。

+0

我shuld写了我的例子更精确,我真的想**重新启动**我的程序! – dacwe 2010-11-17 19:05:35

+0

@dacwe除非需要重新启动才能更新某些配置信息,否则,我认为最好不要在文件中查看更改。改变你的程序设计,以更好地适应动态配置信息,而不是原始的'static final String'。将您全局访问的配置封装在一个类中。 – 2010-11-17 20:19:20

0

这个怎么样结构

public static void main(String... args) { 

    boolean restart = true; 
    while (restart) 
    { 
     retart = runApplication(); 
    } 

} 

如果你发现需要重新启动你的应用程序,有runApplication返回true。 如果是时候退出返回false;

+0

这不会重新初始化任何最终变量。 – dacwe 2010-11-17 19:45:22

0

如果你有一个UI或一个守护进程,所以你可以控制输出到标准输出,你可以在外部打开一个包装器来启动你的程序。

如果程序退出时输出“RESTART”,您可以从这个包装重新启动程序。如果不是,它就结束了。

或者,如果您想要纯java方式,您可以像Peter Lawrey在其文章中提到的那样使用类加载器来解决问题。在走下这条路线之前,你应该重新考虑你的设计(如果它是你的代码)并且让你的代码能够自我清理。

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); 
     } 
    } 
}