Sie können anrufen:
%Vor%Dies lädt die Klasse, ohne dass Sie sie tatsächlich berühren, und führt den statischen Initialisierungsblock aus.
Um die Klasse %code% mit der Factory zu registrieren, muss ihr statischer Initializer aufgerufen werden. Um den statischen Initialisierer der Klasse %code% auszuführen, muss entweder auf die Klasse verwiesen werden oder sie muss durch Reflexion geladen werden, bevor %code% aufgerufen wird. Wenn Sie die Methode %code% unverändert lassen wollen, müssen Sie sie referenzieren oder durch Reflexion im statischen Initiator %code% laden. Ich denke nicht, dass dies eine gute Idee ist, aber ich beantworte nur Ihre Frage :) Wenn es Ihnen nichts ausmacht, dass %code% alle Klassen kennt, die %code% implementieren, können Sie sie direkt referenzieren oder lade sie durch Reflexion. Etwas wie:
%Vor%Stellen Sie sicher, dass sich die Deklaration und Konstruktion von %code% vor dem %code% -Block befindet. Wenn Sie %code% nicht über die Implementierungen von %code% wissen wollen, müssen Sie sie in einer Konfigurationsdatei auflisten, die von %code% geladen wird. Die einzige andere (möglicherweise wahnsinnige) Art, wie ich es mir vorstellen könnte, wäre, durch den gesamten Klassenpfad nach Klassen zu suchen, die %code% implementieren :) Das könnte besser funktionieren, wenn alle Klassen, die %code% implementiert haben, zur gleiches Paket - HINWEIS: Ich befürworte diese Lösung nicht;)
Der Grund, warum ich das im statischen Initializer %code% nicht mache, ist, dass Klassen wie %code% ihren eigenen statischen Initialisierer haben, der in %code% aufruft, was zu diesem Zeitpunkt ein unvollständig konstruiertes Objekt ist. was nur nach Ärger fragt. Mit einer Konfigurationsdatei, die einfach die Klassen auflistet, die %code% konstruieren soll, ist es eine feine Lösung, sie im Konstruktor zu registrieren, aber das würde bedeuten, dass Sie Ihre %code% Methode ändern müssen.
Um die statischen Initialisierer ausführen zu können, müssen die Klassen geladen werden. Dazu muss entweder Ihre Hauptklasse (direkt oder indirekt) von den Klassen abhängen oder sie muss direkt oder indirekt dynamisch geladen werden. z.B. mit %code% .
Ich denke, Sie versuchen, Abhängigkeiten zu vermeiden, die in Ihren Quelltext eingebettet sind . Daher sind statische Abhängigkeiten nicht akzeptabel und Aufrufe von %code% mit fest codierten Klassennamen sind ebenfalls nicht akzeptabel.
Damit bleiben Ihnen zwei Alternativen:
Schreiben Sie etwas unordentlichen Code, um über die Ressourcennamen in einem Paket zu iterieren, und verwenden Sie dann %code% , um die Ressourcen zu laden, die Ihren Klassen ähneln. Dieser Ansatz ist schwierig, wenn Sie einen komplizierten Klassenpfad haben, und ist unmöglich, wenn Ihr effektiver Klassenpfad einen URLClassLoader mit einer entfernten URL (zum Beispiel) enthält.
Erstellen Sie eine Datei (z. B. eine Klassenlader-Ressource), die eine Liste der zu ladenden Klassennamen enthält, und schreiben Sie einen einfachen Code, um die Datei zu lesen, und laden Sie sie mit %code% .
Der statische Initialisierer für die Klasse kann nicht ausgeführt werden, wenn die Klasse niemals geladen wird.
Sie müssen also entweder alle korrekten Klassen laden (was schwierig sein wird, da Sie sie nicht alle zur Kompilierzeit kennen) oder die Anforderung für den statischen Initialisierer loswerden.
Eine Möglichkeit, Letzteres zu tun, ist die Verwendung der %code% .
Mit dem %code% legst du einfach eine Datei in %code% und liesst alle Implementierungen auf. Sie können mehrere solche Dateien haben, eine pro .jar-Datei. Auf diese Weise können Sie einfach weitere %code% Implementierungen separat von Ihrem Hauptprogramm versenden.
In %code% kannst du einfach %code% verwenden, um %code% zu erhalten, was %code% implementiert und wie folgt verwendet werden kann:
%Vor%Ich habe ein paar Klassen wie hier gezeigt
%Vor%...
%Vor%Wie kann ich die %code% -Klasse ändern, so dass die statische Methode immer ausgeführt wird, so dass ich 1 anstelle von 0 bekomme, wenn ich meine Hauptmethode ausführe? Ich will keine Änderung in der Hauptmethode.
Ich versuche tatsächlich, die Fabrikmuster zu implementieren, in denen sich die Unterklassen bei der Fabrik registrieren, aber ich habe den Code für diese Frage vereinfacht.