проблема с отражением Java

#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));
  

в противном случае игнорировать.