2016-07-20 13 views
0

Ich schreibe einen Multiplayer-Spielserver und möchte alle Weltdaten dynamisch aus Dateien laden. Diese Dateien sollten ein Array von Objekten dynamisch laden. Es werden ungefähr drei oder vier verschiedene Arten von Objekten zum Laden von Dateien vorhanden sein, und die Länge des Konstruktorarguments ist unbekannt.Unbekannter Konstruktor mit unbekannter Argumentlänge aufrufen

Ein Beispiel für eine gespeicherte Datei:

arg1, arg2, arg3, arg4 

, die in einem Array aufgeteilt wird

[arg1, arg2, arg3, arg4] 

die dann einen Konstruktor mit diesen Argumenten

new NPC(arg1, arg2, arg3, arg4) 

Hier ist die Methode aufrufen sollte Ich habe gerade

public static <T> void load(String path, Class<T> type) { 
    path = dataDir + path; 
    String content = Util.readFile(path); 
    String[] lines = content.split("\n"); 
    // T[] result = new T[lines.length]; Type paramater 'T' can not be instantiated directly. 
    for (int i = 0; i < lines.length; i++) { 
     String[] args = lines[i].split(", "); 
     // result[i] = new T(args[0], args[1]...); Should add a T to the array with args 'args' 
    } 
    // return result 
} 

Und wie diese

Npc[] npcs = DataLoader.load("npcs.dat"); 
+0

Dies ist nicht genügend Informationen. Was sind die Arten der Argumente? Welchen Code haben Sie geschrieben, der den Typ durch Reflexion instanziiert? Was funktioniert nicht? Um es selbst zu tun, müssen Sie die Argumenttypen kennen, dann mit Reflection nach einem passenden Konstruktor suchen und es dann aufrufen. Das alles wird im Javadoc und in verschiedenen Tutorials behandelt, obwohl es einfach genug ist, dass Sie es aus dem Javadoc alleine herausfinden können. –

+0

Es scheint mir, als wolltest du das Rad hier neu erfinden. Haben Sie die Serialisierung mit 'ObjectOutputStream' und' ObjectInputStream' schon ausgecheckt? –

+0

Nun, die Argumente sind alle in der Datei als Strings gespeichert, so dass sie alle aus Strings konvertiert werden können. Die einzigen Argumenttypen sind also Integer und Strings. Außerdem haben alle Objekte nur einen Konstruktor, daher möchte ich herausfinden können, was die Argumenttypen sind, und die Zeichenfolge automatisch in diesen Typ konvertieren. Ich habe gerade fertig mit der Eingabe, als Ihr Kommentar erschien Andrew, ich werde es versuchen. –

Antwort

1

nennt eine generische Last haben:

public static <T> T[] load(String path, Class<T> type) ... 

Declare Konstrukteure in jeder Klasse ein Array von Strings unter:

public Npc(String[] args) oder public Npc(String... args)

Dann verwenden Sie Reflektion ins ins tantiate generische Typen:

// instantiate a generic array 
T[] result = (T[]) Array.newInstance(type, length); 
// parameterized constructor of generic type, e.g. new T(String[]) 
Constructor<T> constructorOfT = type.getConstructor(String[].class); 
// call the constructor for every position of the array 
result[i] = constructorOfT.newInstance(new Object[] { args }); 

Da load kann mit jeder Art oder der Hersteller möglicherweise nicht verlassen, fangen Reflexion Ausnahmen genannt werden:

catch (ReflectiveOperationException e) { 
     // means caller did not call one of the supported classes (Npc) 
     // or the class does not have the expected constructor 
     // react in some way 
     e.printStackTrace(); 
} 
+0

Danke, das funktioniert super. –