#java
#java
Вопрос:
У меня есть этот код:
public static final <TypeVO extends BaseVo> List<SelectItem> populateSelectBoxForType(
final Class<TypeVO> voClass, final String fieldName) {
List<SelectItem> listSelectBox = null;
final List<TypeVO> vosList = GenericEjbProxyFactory
.getGenericTopValueObjectProxy(voClass)
.getAllValueObjects(null);
System.out.println("loaded vosList!!!!");
if (vosList != null) {
listSelectBox = new ArrayList<SelectItem>();
for (final TypeVO currVo : vosList) {
listSelectBox.add(new SelectItem(currVo.getInternalId(), currVo.getName()));
}
}
return listSelectBox;
}
Как вы видите здесь, я использую currVo.getName, потому что у currVo всегда есть свойство name.
Я хочу иметь возможность использовать также другие поля из этого currVo, тип которого равен voClass, но не все классы currVo будут содержать это поле, поэтому я должен использовать отражение для идентификации этого метода getField, что-то вроде:
for (final TypeVO currVo : vosList) {
for (final Method m : voClass.getMethods()) {
if (m.getName().contains(fieldName)) {
listSelectBox.add(new SelectItem(
currVo.getInternalId(), currVo.m));
}
}
}
Чего я не знаю, ТАК это КАК я могу использовать значение этого конкретного метода, когда нахожу его, точно так же, как currVo.getName (потому что, конечно, currVo.m неверно)?
Например: если имя поля равно «возрасту», я хочу добавить в список: currVo.getAge()
… Я просто заблокирован здесь…
Ответ №1:
m.invoke(currVo);
Смотрите также:
Также обратите внимание на правильный способ поиска метода, предложенный Ником и Богеманом.
Комментарии:
1.
invoke
принимает два аргумента.2. @Mat: Он принимает vararg в качестве второго аргумента, который может быть пустым.
3. спасибо за новый совет по подписи — не понял, что отражение стало varargs
Ответ №2:
Правильно ли я понимаю, что вы хотите вызвать метод m
для вашего объекта currVo
? Тогда это просто
m.invoke(currVo);
Ответ №3:
Используйте отражение, чтобы получить метод GetFieldName и вызвать его следующим образом:
Method method = voClass.getMethod("get" fieldName); // the getter with no params in the signature
Object value = method.invoke(currVo}); // invoke with no params
listSelectBox.add(new SelectItem(currVo.getInternalId(), value));
Примечание: Предполагается, что имя поля указано в верхнем регистре, например «Значение», а не «value», поэтому добавление к нему «get» дает точное имя метода, например «GetValue»
Ответ №4:
Вы должны использовать invoke
метод из Method
класса.
m.invoke(currVo, (Object[]) null);
(Предполагается, что метод не принимает параметров.)
Это будет работать для JDK версий 1.4 и более поздних, поскольку в них указано:
Если количество формальных параметров, требуемых базовым методом, равно 0, предоставленный массив args может иметь длину 0 или null
Однопараметрическая версия этого вызова не будет работать на старых JVM.
Комментарии:
1. Это то же самое, что
m.invoke(currVo, new Object[] { null });
что может быть не тем, что вы предполагали.2. я также не согласен — значение null является значением и делает Object[] length 1 — оно должно быть нулевой длины
3. Вы правы. null «преобразуется» в
Object[]
не как массив длиной 0 или 1.4. Однако я был немного не в себе, явное приведение к
Object[]
необходимо для его компиляции без предупреждений, по крайней мере, в версии 1.6.
Ответ №5:
Я не уверен, правильно ли я понял ваш вопрос, но, как мне кажется, на то, что вы просите, ответит следующий код:
// Class is whatever is the type u r using
Method mthd = Class.getMethod("get" fieldName); //in case method don't have any parameters.
listSelectBox.add(mthd.invoke(currVo));
в противном случае игнорировать.