Was ist der richtige Weg für die Verwendung von Reflektion, um Objekte unbekannter Klassen zur Laufzeit zu instanziieren?

8

Ich arbeite an einer Configuration Loader-Klasse, so dass ich die Parameter meines Programms über eine externe Textdatei (config.txt) ändern kann, anstatt meinen Code bei jeder Änderung neu kompilieren zu müssen.

Es wurde vorgeschlagen, dass ich dazu Reflection von Java benutze, aber ich bin ein wenig verwirrt darüber, wie ich das tatsächlich umsetzen könnte.

Ich konnte erfolgreich den Klassennamen und die Argumente für seinen Konstruktor aus meiner Textdatei extrahieren, aber wie gehe ich von diesem zu einem instanziierten Objekt über?

hier ist, was ich bisher von meiner Methode habe:

%Vor%

classString ist eine Zeichenfolge, die den Namen der Klasse enthält, und hm ist eine hashmap, in der die Konstruktorparameter der Klasse ihren beabsichtigten Werten zugeordnet werden.

Das heißt, für class Foo (int xPos, float yPos) würde "xPos" einer Zeichenkette des int int und "yPos" einer Zeichenkette des beabsichtigten Floats zugeordnet. Ich möchte zurückgeben können, new Foo(hm.get"xPos".toInt, hm.get"yPost".toFloat) , aber ich bin unsicher, wie man einen Konstruktor wie diesen dynamisch verwenden kann (das Problem ist, dass es mehrere mögliche Klassen gibt - vielleicht ist es ein bar anstelle von foo , zum Beispiel).

Ich weiß, dass es möglich ist, ein if / else basierend auf dem classString zu machen, und einfach den richtigen Konstruktor aufzurufen, nachdem ich es identifiziert habe, aber ich möchte einen erweiterbaren Code erstellen, der nicht jedes Mal neu geschrieben werden muss Ich füge dem Programm eine neue Klasse hinzu.

Alle möglichen Objekte erben von einem einzelnen übergeordneten Objekt.

    
Raven Dreamer 08.10.2011, 16:35
quelle

3 Antworten

14

Sie würden Class.getConstructor(Class<?>... parameterTypes) verwenden, um einen Verweis auf den Konstruktor zu erhalten, gefolgt von Constructor.newInstance(Object... initargs) .

Ich würde jedoch vorschlagen, einen Blick auf ein Abhängigkeitsinjektions-Framework wie Spring oder Guice zu werfen, da es sich anhört, dass das, was Sie erstellen, eine grundlegende Version dessen ist, was sie tun.

Auf Anfrage, um diese Antwort zu erweitern:

%Vor%

Natürlich würden Sie anstelle von param1 und param2 ein Array von Argumenten erstellen, basierend auf dem, was in der Eingabedatei war (das gleiche gilt für die Argumente für getConstructor() ), usw.

    
matt b 08.10.2011, 16:40
quelle
3

Hier ist ein Beispiel dafür, wie man es aus Programmargumenten macht:

%Vor%

Natürlich kann die argList in diesem Fall immer nur Strings haben, weil sie von einem String[] gezogen werden, aber Sie können Args jeden Typs hinzufügen. Beachten Sie, dass Konstruktorargumente positionsabhängig und nicht benannt sind, sodass die Namen in der Map nicht besonders gut sind. Sie müssen in der richtigen Reihenfolge sein.

Versuchen Sie es auszuführen und übergeben Sie "java.util.Date" als Argument.

    
Ryan Stewart 08.10.2011 17:26
quelle
1
%Vor%     
MasterCassim 08.10.2011 16:40
quelle

Tags und Links