"Итерация" с помощью методов
Скажем, у меня есть объект 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) + " | ";
}
Спасибо за ваши идеи.
Ответы
Ответ 1
Существует способ использования отражения:
try{
Method m= object.getClass().getMethod("getField"+String.valueOf(i), new Class[]{});
fields+=(String)m.invoke(object);
}catch(...){...}
Однако:
Этот бизнес пахнет плохой практикой кодирования!
Не можете ли вы переписать все методы getFieldN()
, подобные этому?
String getField(int fieldNum)
Вы запрашиваете проблемы, создавая нумерованные методы. Помните, что отражение медленное и должно использоваться только тогда, когда вызовы методов на основе String абсолютно необходимы для потока вашей программы. Я иногда использую эту технику для пользовательских языков сценариев, где вам нужно получить метод по имени. Это совсем не так, ваши вызовы с индексом integer. Поэтому вы должны сохранить целое число как параметр.
Если это устаревший код, и вы абсолютно не можете изменить это плохое кодирование, вам может быть лучше создать новый метод getMethod(int)
, как описано выше, чтобы обернуть существующие методы, которые просто делегируют нумерованные методы getMethodN()
.
Ответ 2
Class yourClass = YourClass.class;
for (Method method : yourClass.getMethods()){
method.invoke(obj, args);
}
См. это руководство для справки.
Ответ 3
Чтобы иметь возможность выбирать определенные поля и порядок, вы должны указать их, т.е. список имен полей.
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", "|" ));
}
}