2016-07-20 5 views
0

Я пишу многопользовательский игровой сервер, и я хочу динамически загружать все данные мира из файлов. Эти файлы должны динамически загружать массив объектов. Для загрузки из файлов будет около трех или четырех разных типов объектов, а длины аргументов конструктора неизвестны.Вызов неизвестного конструктора с неизвестной длиной аргумента

Пример сохраненного файла:

arg1, arg2, arg3, arg4 

Что разбивается на массив

[arg1, arg2, arg3, arg4] 

Который должен затем вызвать конструктор с этими аргументами

new NPC(arg1, arg2, arg3, arg4) 

Вот метод Я имею прямо сейчас

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 
} 

И это называется, как этот

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

Это недостаточная информация. Каковы типы аргументов? Какой код вы написали, который создает экземпляр типа посредством отражения? Что не работает? Чтобы сделать это самостоятельно, вам нужно знать типы аргументов, затем использовать отражение для поиска соответствующего конструктора, а затем вызвать его. Все это описано в Javadoc и различных учебных пособиях, хотя это достаточно просто, чтобы вы могли понять это только от Javadoc. –

+0

Мне кажется, что вы пытаетесь изобрести колесо здесь. Вы проверили сериализацию с 'ObjectOutputStream' и' ObjectInputStream'? –

+0

Ну, все аргументы хранятся в файле как строки, поэтому все они могут быть преобразованы из строк. Таким образом, единственными типами аргументов будут целые числа и строки. Кроме того, у всех объектов есть только один конструктор, поэтому я бы хотел найти типы аргументов и автоматически преобразовать строку в этот тип. Я только что набрал это, когда появился ваш комментарий Andrew, я попробую это. –

ответ

1

Чтобы иметь общую нагрузку:

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

DECLARE Конструкторы в каждом классе принимают массив строк:

public Npc(String[] args) или public Npc(String... args)

Затем используйте отражение для вставки tantiate общих типов:

// 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 }); 

С load можно назвать с любым типом или конструктор не может выйти из, перехватывать исключение отражения:

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

Спасибо, это отлично работает. –

Смежные вопросы