Отражение Java: получение типа возвращаемого параметра метода
Да, я знаю, что есть много статей на эту тему, но это не так просто.
У меня есть класс-оболочка, который используется для общей передачи аргументов в методы и последующего получения значений. Этот класс-обертка (называется IDVariant
) имеет тип по умолчанию, который указывает основной тип хранимой переменной.
Следовательно, я могу иметь:
IDVariant v = new IDVariant(1);
boolean b = v.booleanValue();
String s = v.stringValue();
int i = v.integerValue();
и так далее, но тип по умолчанию будет int
в соответствии с типом параметра, используемого для создания экземпляра.
Теперь этот класс, как уже упоминалось, используется в качестве основного заполнителя в гораздо больших и более сложных классах. Мне нужно создать инструмент, который рекурсивно анализирует суперструктуру классов и воссоздает эту структуру в XML. Очевидно, что путь - это Размышление, и я до сих пор добивался успеха в воссоздании структуры всего этого. Единственная проблема в том, что я не нашел способа узнать тип IDVariant по умолчанию и, таким образом, иметь правильный тип для каждой переменной дерева XML.
То, что я пытался сделать, это получить get
метод для каждого свойства каждого класса, затем вызывая его и проверяя тип по умолчанию для каждого IDVariant. Это казалось хорошей идеей, но она не работает: я получаю 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, я проверил исходный код. Однако я не могу изменить этот код, так как он исходит от внешнего инструмента, который генерирует его автоматически.
Заранее спасибо:)
РЕДАКТИРОВАТЬ: Хорошо, поэтому я лучше посмотрел на источник, созданный внешним инструментом, и вот что я собираю:
Я использую пример метода, скажем, getSomeValue
, В источнике класса, где объявлен метод, вот объявление метода:
public IDVariant getSomeValue() { return GetPropDirect(externalValue); }
Так что, возможно, он внутренне пытается вызвать другой метод, который принадлежит суперклассу, и я не создаю экземпляр суперкласса. Возможно ли, что это проблема? И если да, есть ли обходной путь?
РЕДАКТИРОВАТЬ 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
1 ответ
Ваш IDVariant
класс, конечно, создается, вот что вы делаете с toParse.newInstance()
метод, но поскольку вы не приводите экземпляр объекта к его исходному типу класса, а затем инициализируете его, существует большая вероятность исключения, например NullPointerEx.