Mehrere Instanzen von statischen Variablen
Ich experimentiere mit unterschiedlichen classloadern geladen einer bestimmten Klasse, und sehen, ob die statischen Variablen, die in dieser Klasse kann über verschiedene Instanzen.
Grundsätzlich, ich versuche, code zu schreiben, für das, was Stephen C erwähnt hat in diese Antwort.
Hier sind meine Klassen:
CustomClassLoader.java
class CustomClassLoader extends ClassLoader
{
public Class loadClass(String classname) throws ClassNotFoundException {
return super.loadClass(classname, true);
}
}
Test.java (enthält die Treiber)
class Test {
public static void main(String[] args) throws Exception {
CustomClassLoader c1 = new CustomClassLoader();
CustomClassLoader c2 = new CustomClassLoader();
Class m1, m2;
m1 = c1.loadClass("A");
m2 = c2.loadClass("A");
m1.getField("b").set(null, 10);
System.out.println(m1.getField("b").get(null));
System.out.println(m2.getField("b").get(null));
}
}
A.java (enthält die statische variable)
class A {
public static int b = 5;
}
Wenn ich den Test Klasse, ich bekomme die folgende Ausgabe:
$ java Test
10
10
Erwartete ich den Ausgang auf 10 und 5. Wie kann ich den code erstellen Sie zwei Instanzen von meiner statische variable?
Hinweis: ich mache das nur zum Experimentieren und lernen - aber ich wäre daran interessiert zu wissen, wenn es könnte eine Reale Anwendung dieser.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es sieht aus, als wenn die Klasse "A" wird geladen, indem der parent class loader, anstatt Ihre CustomClassLoader (weil Sie call super.loadClass).
Folgende ungetestete änderung sollte Ihnen ermöglichen, definieren Sie die Klasse "A" mit Ihren eigenen class loader (delegieren alles andere zu den übergeordneten loader).
Entschuldigungen für die schrecklichen bodge, wo ich nehme an, die einzelnen inputStream.read() liest alles! Aber man kann hoffentlich sehen, was ich meine.
Wahrscheinlich werden Sie dann am Ende mit ClasscastExceptions oder etwas ähnliches...
super.loadClass()
. Könnten Sie empfehlen, keine gute Quelle, die erklärt, dass?b
:Exception in thread "main" java.lang.IllegalAccessException: Class Test can not access a member of class A with modifiers "public static"
.A
öffentlichkeit.Dein problem ist, dass
new CustomClassLoader()
schafft ein classloader implementiert, der versuchen wird, um zu delegieren, laden der Klassen auf den system-classloader - und das wird der gleiche sein für beide Instanzen. IhreCustomClassLoader
auch gar nicht in der Lage, um Klassen zu laden selbst. Versuchen Sie es mit einemURLClassLoader
und Weitergabenull
als Elternteil.Als für die Reale Welt-Anwendungen: es ist essentiell für Java-Web-Container und app-Servern, indem Sie unterschiedliche apps werden komplett voneinander isoliert, obwohl Sie über viele der gleichen Klassen.
Wenn man sich an den ClassLoader Quelle oder sogar javadocs finden Sie heraus, dass standardmäßig der ClassLoader die Delegierten der Standard-system-ClassLoader, die in der Tat ist geteilt zwischen den Instanzen.
Ich hatte das gleiche problem (integration tests) und versucht es mit @Michael Borgwardt Ansatz. Hier einige Beispiel-code: