20

假设我有一个 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) + " | ";
}

感谢您即将提出的想法。

4

3 回答 3

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

请参阅本指南以供参考。

于 2010-07-23T08:40:49.717 回答
11

有一种使用反射的方法:

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

然而: 这个行业充满了糟糕的编码习惯!你不能getFieldN()像这样重写所有的方法吗?

String getField(int fieldNum)

您通过创建编号方法来自找麻烦。请记住,反射很慢,并且只应在基于字符串的方法调用对您的程序流程绝对必要时使用。我有时将这种技术用于用户定义的脚本语言,在这种语言中,您必须按名称获取方法。这里根本不是这种情况,您的调用是integer-indexed。因此,您应该将整数保留为参数。

如果这是遗留代码并且您绝对无法更改这种糟糕的编码,那么您最好创建一个getMethod(int)如上所述的新方法来包装现有方法,该方法仅代表编号getMethodN()方法。

于 2010-07-23T08:43:52.533 回答
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", "|" ));
    }
}
于 2010-07-23T09:06:25.723 回答