遍历方法

22

假设我有一个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个回答

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

参考此指南


我想我忘了提到,我的类还有其他方法,我不想调用。你的代码还能完成任务吗? - user321068
1
如果您知道方法签名,就可以在 method.getName()method.getParameterTypes() 的基础上仅调用它们。 - Alberto Zaccagni

12

可以使用反射方式:

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
为了能够选择特定的字段和排序,您应该明确指定它们,例如通过一个字段名称的列表。
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", "|" ));
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接