“Итерация” через методы

Скажем, у меня есть объект Java, это получено среди других следующие методы:

public String getField1();
public String getField2();
public String getField3();
public String getField4();
public String getField5();

Существует ли способ выполнить итерации через эти методы и назвать их как следующий код?

String fields = "";
for(int i = 1; i <= 5; i ++){
   fields += object.(getField+i) + " | ";
}

Спасибо за Ваши предстоящие идеи.

14
задан 23 July 2010 в 08:38
поделиться

3 ответа

Есть способ с использованием отражения:

try{
  Method m= object.getClass().getMethod("getField"+String.valueOf(i), new Class[]{});
  fields+=(String)m.invoke(object);
}catch(...){...}

Однако: Все это дело попахивает плохой практикой кодирования! Разве вы не можете переписать все методы getFieldN() подобным образом?

String getField(int fieldNum)

Создавая нумерованные методы, вы сами навлекаете на себя неприятности. Помните, что отражение работает медленно и должно использоваться только тогда, когда вызовы методов на основе строк абсолютно необходимы для работы вашей программы. Иногда я использую эту технику для пользовательских скриптовых языков, где нужно получить метод по имени. В данном случае это совсем не так, ваши вызовы индексированы по целому числу. Поэтому вы должны сохранить целое число в качестве параметра.

Если это унаследованный код, и вы абсолютно не можете изменить эту плохую кодировку, тогда вам лучше создать новый метод getMethod(int), как описано выше, чтобы обернуть существующие методы, который просто делегирует нумерованные методы getMethodN().

9
ответ дан 1 December 2019 в 12:12
поделиться
Class yourClass = YourClass.class;
for (Method method : yourClass.getMethods()){
    method.invoke(obj, args);           
}

См. данное руководство для справки.

15
ответ дан 1 December 2019 в 12:12
поделиться

Чтобы иметь возможность выбирать конкретные поля и порядок, необходимо задать их, т.е. список имен полей.

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.StringTokenizer;

public class CsvReflect {
    int a = 10;
    String b = "test";
    Date d = new Date();

    public int getA() {
        return a;
    }

    public String getB() {
        return b;
    }

    public Date getD() {
        return d;
    }

    public static String toCsv(Object obj, String fields, String separator) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        StringBuilder sb = new StringBuilder();
        StringTokenizer st = new StringTokenizer(fields,",");
        while ( st.hasMoreElements() ) {
            String field = st.nextToken();
            Method getter = obj.getClass().getMethod("get"+ field, new Class[]{});
            String val = "" + getter.invoke(obj, new Class[]{});
            sb.append( val );
            if ( st.hasMoreElements() ) {
                sb.append(separator);
            }
        }
        return sb.toString();
    }
    public static void main(String[] args) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        CsvReflect csv  = new CsvReflect();
        System.out.println( csv.toCsv( csv ,"A,B,D", "|" ));
    }
}
0
ответ дан 1 December 2019 в 12:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: