2010-07-23 4 views
11

Скажем, у меня есть объект 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) + " | "; 
} 

Благодарим вас за наступающие идеи.

ответ

8

Существует способ использования отражения:

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-indexed. Поэтому вы должны сохранить целое число как параметр.

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

14
Class yourClass = YourClass.class; 
for (Method method : yourClass.getMethods()){ 
    method.invoke(obj, args);   
} 

См. this guide для справки.

+0

Я, наверное, забыл упомянуть, что у моего класса есть и другие методы, которые я не хочу вызывать. Будет ли ваш код по-прежнему выполнять работу? – 2010-07-23 08:42:48

+1

Если вы знаете свои подписи, вы можете вызывать только их, основываясь на 'method.getName()' и на 'method.getParameterTypes()' –

0

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

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", "|")); 
    } 
} 
Смежные вопросы