Да, я знаю, что на эту тему есть много статей, но это не так просто.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
Итак, что находится в переменной 'o'? Если 'getSomeValue' бросает исключение, то шансы высоки, из-за того, что находится в' o'. – cyon
Вы правы, я забыл добавить определение для 'o'. Я отредактировал код, чтобы указать это. Однако при отладке я вижу, что объект 'o' создается, он имеет все значения, которые он должен, хотя большинство из них имеют значение null. Должен ли я использовать конструктор 'Constructor' по умолчанию вместо использования метода, который я сейчас использую? Спасибо за ваше время ... :) – IMIordanov
Поскольку тип возврата не является частью подписи метода. Я не знаю, возможно ли то, что вы просите. –