Java:如何“重启”静态类?

我有一个静态类(Foo)和一个主类(Main)

请参阅Main.java:

public class Main { public static void main(String[] args) { System.out.println(Foo.i); // 0 Foo.i++; System.out.println(Foo.i); // 1 // restart Foo here System.out.println(Foo.i); // 1 again...I need 0 } } 

见Foo.java:

 public class Foo { public static int i = 0; } 

有没有办法重启或重置静态类?

注意:我需要这个,因为我正在使用jUnit测试静态类,我需要在第二次测试之前清理参数。


编辑

几乎解决方案:

使用StanMax答案,我可以这样:

Main.java

 public class Main { public static void main(String[] args) throws Exception { test(); test(); } public static void test() throws Exception { System.out.println("\ntest()"); MyClassLoader myClassLoader = new MyClassLoader(); Class fooClass = myClassLoader.loadClass(Foo.class.getCanonicalName()); Object foo = fooClass.newInstance(); System.out.println("Checking classloader: " + foo.getClass().getClassLoader()); System.out.println("GC called!"); System.gc(); } } 

MyClassLoader.java

 public class MyClassLoader { private URLClassLoader urlClassLoader; public MyClassLoader() { try { URL url = new File(System.getProperty("user.dir") + "/bin/").toURL(); URL[] urlArray = {url}; urlClassLoader = new URLClassLoader(urlArray, null); } catch (Exception e) { } } public Class loadClass(String name) { try { return (Class) urlClassLoader.loadClass(name); } catch (Exception e) { } return null; } @Override protected void finalize() throws Throwable { System.out.println("MyClassLoader - End."); } } 

Foo.java

 public class Foo { public static int i = 0; static { System.out.println("Foo - BEGIN ---------------------------------"); } public void finalize() throws Throwable { System.out.println("Foo - End."); } } 

OUTPUT

 test() Foo - BEGIN --------------------------------- Checking classloader: java.net.URLClassLoader@ec160c9 GC called! MyClassLoader - End. Foo - End. test() Foo - BEGIN --------------------------------- Checking classloader: java.net.URLClassLoader@ec3fb9b GC called! MyClassLoader - End. Foo - End. 

问题:如果我做了演员:

 Foo foo = (Foo) fooClass.newInstance(); 

我收到错误:

 java.lang.ClassCastException 

只有当你可以卸载类时,才能重新加载它,因为在加载类时会执行类静态代码。

但你可以直接修改值:

 Foo.i = 0; 

(或创建相同的方法,特别是如果静态成员不公开)

避免静电。

众所周知,静电是不可测试的,因此应该避免。 例如,避免静态是dependency injection背后的关键动机之一。 如果仅在运行时需要一个实例,请改用单例模式。 并为每个测试运行创建一个新实例。

创建一个静态方法,将类变量设置为初始值,然后在需要时调用它。

你可以试试这个。

 Main MainObject = new Main; MainObject.main(args); 

它会一次又一次地重启课程,直到你停止上课。