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);
он будет перезапускать класс снова и снова, пока вы не остановите класс.