«Итерация» через методы - PullRequest
14 голосов
/ 23 июля 2010

Допустим, у меня есть 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) + " | ";
}

Спасибо за ваши будущие идеи.

Ответы [ 3 ]

15 голосов
/ 23 июля 2010
Class yourClass = YourClass.class;
for (Method method : yourClass.getMethods()){
    method.invoke(obj, args);           
}

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

9 голосов
/ 23 июля 2010

Есть способ, использующий отражение:

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() методам. .

0 голосов
/ 23 июля 2010

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

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", "|" ));
    }
}
...