Java:如何"重启"静态类?

Top*_*era 10 java junit static

我有一个静态类(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
    }

}
Run Code Online (Sandbox Code Playgroud)

见Foo.java:

public class Foo {

    public static int i = 0;

}
Run Code Online (Sandbox Code Playgroud)

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

注意:我需要这个,因为我正在使用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();
    }

}
Run Code Online (Sandbox Code Playgroud)

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


}
Run Code Online (Sandbox Code Playgroud)

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


}
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

问题:如果我做了演员:

Foo foo = (Foo) fooClass.newInstance();
Run Code Online (Sandbox Code Playgroud)

我收到错误:

java.lang.ClassCastException
Run Code Online (Sandbox Code Playgroud)

Sta*_*Man 3

仅当您可以卸载类时,才重新加载它,因为类加载时会执行类静态代码。

但你可以直接修改该值:

Foo.i = 0;
Run Code Online (Sandbox Code Playgroud)

(或者创建等效方法来执行此操作,特别是如果静态成员不是公共的)