0

Да, я знаю, что на эту тему есть много статей, но это не так просто.Java Reflection: получение типа возвращаемого параметра метода

У меня есть класс-оболочка, который используется для общего прохождения аргументов методам и последующего извлечения значений. Этот класс-оболочка (IDVariant) имеет тип по умолчанию, который указывает основной хранимый тип переменной.

Таким образом, я могу иметь:

IDVariant v = new IDVariant(1); 
boolean b = v.booleanValue(); 
String s = v.stringValue(); 
int i = v.integerValue(); 

и так далее, но по умолчанию тип будет int, в соответствии с типом параметра, используемого для создания экземпляра.

Теперь этот класс, как уже упоминалось, используется в качестве общего заполнителя в гораздо более крупных и более сложных классах. Мне нужно создать инструмент, который рекурсивно разбирает суперструктуру классов и воссоздает эту структуру в XML. Очевидно, что путь - это Reflection, и я до сих пор был успешным в воссоздании структуры всего этого. Единственная проблема заключается в том, что я не нашел способ узнать тип IDVariant по умолчанию и, следовательно, иметь правильный тип для каждой переменной дерева XML.

Что я пытался сделать, это получить метод get для каждого свойства каждого класса, затем вызвать его и проверить тип по умолчанию каждого IDварианта. Это казалось хорошей идеей, но она не работает: я получаю InvocationTargetException, который, я полагаю, связан с тем, что экземпляр класса, который я создал для вызова метода, на самом деле не заполнен данными. Это единственное логическое объяснение, которое я смог дать.

Если у кого-нибудь есть идеи, я был бы очень благодарен! :)

Ниже приведен фрагмент пример кода:

// Edit of the code, as correctly indicated by cyon. Tha variable className is given. 
Class<?> toParse = Class.forName(className); 
Object o = toParse.newInstance(); // There is a default constructor with no values, the object is not null 

Class cl = ... // given class 
Class[] noparams = {}; 

String s = "getSomeValue"; 
Method method = null; 
for(Method m : cl.getMethods()) { 
    if (m.getName().equals(s)) { 
     method = m; 
     break; 
    } 
} 

if (method != null) { 
    try { 
     Object idv = method.invoke(o, noparams); // exception occurs at this point 
     String type = decodeType((IDVariant)idv); // function which maps internal codes of IDVariant default type to primitive and internal types 
     return type; 
    } catch (InvocationTargetException ex) { 
     System.out.println(ex.getCause()); 
    } 
} 

Примечание: Функция возвращает действительно переменную типа IDVariant, я проверил исходный код из. Однако я не могу изменить этот код, поскольку он поступает из внешнего инструмента, который автоматически генерирует его.

Спасибо заранее :)

EDIT: Хорошо, так что у меня было лучше смотреть на источник создаваемого внешнего инструмента, и это то, что я понимаю:

Я Вызов образец метода, скажем getSomeValue. В источнике класса, в котором объявлен метод, здесь объявление метода:

public IDVariant getSomeValue() { return GetPropDirect(externalValue); } 

Таким образом, возможно, он внутренне пытается вызвать другой метод, который принадлежит к суперклассу, и я не экземпляр суперкласса , Возможно ли, что это проблема? И если да, есть ли обходной путь?

EDIT 2: В соответствии с просьбой, вот трассировки стека для исключения я получаю:

java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at prove.Reflector.getImplicitType(Reflector.java:275) 
    at prove.Reflector.recurr(Reflector.java:134) 
    at prove.Reflector.ParseToXml(Reflector.java:69) 
    at prove.Main.main(Main.java:12) 
Caused by: java.lang.NullPointerException 
    at com.progamma.doc.IDDocument.GetPropDirect(IDDocument.java:739) 
    at it.zerounoesse.Calcolo7302013.Contribuente.getSomeValue(Contribuente.java:70) 
... 8 more 
+0

Итак, что находится в переменной 'o'? Если 'getSomeValue' бросает исключение, то шансы высоки, из-за того, что находится в' o'. – cyon

+0

Вы правы, я забыл добавить определение для 'o'. Я отредактировал код, чтобы указать это. Однако при отладке я вижу, что объект 'o' создается, он имеет все значения, которые он должен, хотя большинство из них имеют значение null. Должен ли я использовать конструктор 'Constructor' по умолчанию вместо использования метода, который я сейчас использую? Спасибо за ваше время ... :) – IMIordanov

+0

Поскольку тип возврата не является частью подписи метода. Я не знаю, возможно ли то, что вы просите. –

ответ

0

Ваш IDVariant класс конечно реализованным, вот что вы делаете с toParse.newInstance() методом, но так как вы не перечислить экземпляр объекта к его первоначальному типу класса и затем инициализировать его, существует большая вероятность исключения, например NullPointerEx.

+0

Что это значит? Построенный объект уже инициализирован. Никакое количество кастингов не изменит это. – EJP

+0

Не в этом случае, спрашивающие 'IDVariant v = new IDVariant (1);' принимает значение в конструкторе, поэтому, если вызывается пустой конструктор, поля класса - nulls => методы класса вызова могут приводить к NPE. Вот почему инициализация поля должна выполняться через сеттеры (требуется листинг) или через рефлекс «Конструктор». – awb

+0

Да, я думаю, что AWB прав. Ваш пост заставил меня искать альтернативу, и, похоже, я что-то нашел. Если это сработает, я отправлю его здесь для дальнейшего использования. – IMIordanov

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