tengo una clase estática (Foo) y una clase principal (Main)Java: ¿cómo "reiniciar" una clase estática?
Ver 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
}
}
Ver Foo.java:
public class Foo {
public static int i = 0;
}
¿Hay alguna manera de reiniciar o restablecer una clase estática?
Nota: Necesito esto porque estoy probando una clase estática con jUnit y necesito limpiar los parámetros antes de la segunda prueba.
EDITAR
CASI SOLUCIÓN:
Usando respuesta StanMax, lo que pueda para esto:
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.");
}
}
SALIDA
test()
Foo - BEGIN ---------------------------------
Checking classloader: [email protected]
GC called!
MyClassLoader - End.
Foo - End.
test()
Foo - BEGIN ---------------------------------
Checking classloader: [email protected]
GC called!
MyClassLoader - End.
Foo - End.
PROBLEMA: si hago el elenco abajo:
Foo foo = (Foo) fooClass.newInstance();
me sale error:
java.lang.ClassCastException
Para este ejemplo en particular, simplemente haga 'Foo.i = 0;' dentro de su método 'Principal'. – LukeH
Tiene ClassCastException porque la clase Foo cargada por URLClassLoader es diferente de la clase Foo cargada por ClassLoader que ejecuta su código (no son ==). Incluso si tienen la misma definición exacta, no puedes lanzar una a la otra. La única forma de que este tipo de truco funcione es si Foo implementa una interfaz FooInterface que es cargada por un ClassLoader que se comparte entre los dos cargadores de clases, en cuyo caso puede enviarlo a FooInterface. Pero eso no ayuda a acceder a los campos estáticos. – NamshubWriter
NamshubWriter: bien, hice esto ... pero el problema principal es porque estoy usando un tipo dinámico ... me aparece "fooClass no puede resolverse en un tipo". Tal vez algo en Refletion API pueda ayudar ... – Topera