2010-07-23 16 views
11

Hãy nói rằng tôi đã có một đối tượng Java ấy có những người khác các phương pháp sau:"lặp" thông qua phương pháp

public String getField1(); 
public String getField2(); 
public String getField3(); 
public String getField4(); 
public String getField5(); 

Có cách nào để lặp qua những phương pháp và gọi 'em như đoạn code sau đây?

String fields = ""; 
for(int i = 1; i <= 5; i ++){ 
    fields += object.(getField+i) + " | "; 
} 

Cảm ơn các ý tưởng sắp tới của bạn.

Trả lời

8

Có một cách sử dụng phản ánh:

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

Tuy nhiên: kinh doanh này tất cả mùi của thực hành mã hóa xấu! Bạn không thể viết lại tất cả các phương pháp getFieldN() như thế này?

String getField(int fieldNum) 

Bạn đang gặp khó khăn bằng cách tạo phương pháp được đánh số. Hãy nhớ rằng sự phản chiếu chậm và chỉ nên được sử dụng khi các cuộc gọi phương thức dựa trên chuỗi là hoàn toàn cần thiết cho luồng của chương trình của bạn. Đôi khi tôi sử dụng kỹ thuật này cho các ngôn ngữ kịch bản do người dùng xác định nơi bạn phải có phương thức theo tên. Đó không phải là trường hợp ở đây, các cuộc gọi của bạn là số nguyên được lập chỉ mục. Do đó, bạn nên giữ nguyên nguyên như một tham số. Nếu đây là mã kế thừa và bạn hoàn toàn không thể thay đổi mã hóa xấu này, thì bạn có thể nên tạo phương thức mới getMethod(int) như trên để bọc các phương thức hiện có, chỉ ủy quyền cho các phương thức được đánh số là getMethodN().

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

Xem this guide để tham khảo.

+0

Tôi đoán tôi đã quên đề cập đến, lớp của tôi cũng có các phương pháp khác mà tôi không muốn gọi. Mã của bạn vẫn sẽ làm công việc sau đó? –

+1

Nếu bạn biết chữ ký của họ, bạn chỉ có thể gọi chúng dựa trên 'method.getName()' và trên 'method.getParameterTypes()' –

0

Để có thể chọn các trường cụ thể và thứ tự bạn nên chỉ định chúng bằng cách liệt kê danh sách tên trường.

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