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

时间:2011-01-08 00:31:26

标签: static junit 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测试一个静态类,我需要在第二次测试之前清理参数。


修改

ALMOST SOLUTION:

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


}

输出

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

4 个答案:

答案 0 :(得分:4)

避免静电。

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

答案 1 :(得分:3)

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

答案 2 :(得分:3)

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

但你可以直接修改价值:

Foo.i = 0;

(或创建等效的方法,例如,如果静态成员不公开)

答案 3 :(得分:-5)

你可以试试这个。

Main MainObject = new Main;

MainObject.main(args);

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