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


}

Фу.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 ответов


только если вы можете выгрузить класс, загрузите его повторно, так как статический код класса выполняется при загрузке класса.

но вы можете просто напрямую изменить значение:

Foo.i = 0;

(или создайте эквивалентный метод для этого, esp. если статический член не является общедоступным)


избежать статического.

хорошо известно, что статика не поддается проверке и поэтому ее следует избегать. Например, избегание статики является одной из ключевых мотиваций инъекции зависимостей. Если вам нужен только один экземпляр во время выполнения, используйте шаблон singleton. И создайте новый экземпляр для каждого тестового запуска.


создайте статический метод, который устанавливает переменные класса в их начальные значения, а затем вызовите его, когда вам это нужно.


вы можете попробовать это.

Main MainObject = new Main;

MainObject.main(args);

он будет перезапускать класс снова и снова, пока вы не остановите класс.