2010-04-14 79 views
99

我需要獲取具有特定註釋的字段的值,所以通過反射我能夠獲得此Field對象。問題是,這個領域將永遠是私人的,雖然我事先知道它總是有一個getter方法。我知道我可以使用setAccesible(true)並獲取它的值(當沒有PermissionManager時),但我更願意調用它的getter方法。通過反射調用getter的最佳方式

我知道我可以通過查找「get + fieldName」來尋找方法(儘管我知道例如boolean字段有時被命名爲「is + fieldName」)。

我不知道是否有更好的方法來調用這個getter(許多框架使用getters/setter來訪問屬性,所以也許他們以另一種方式)。

感謝

回答

195

我想這應該指向你朝着正確的方向:

import java.beans.* 

for (PropertyDescriptor pd : Introspector.getBeanInfo(Foo.class).getPropertyDescriptors()) { 
    if (pd.getReadMethod() != null && !"class".equals(pd.getName())) 
    System.out.println(pd.getReadMethod().invoke(foo)); 
} 

需要注意的是,你可以不使用內部檢查創建的BeanInfo或PropertyDescriptor的情況下自己,即。然而,Introspector在內部做了一些緩存,通常是一件好事(tm)。如果你沒有一個緩存很高興,你甚至可以去

// TODO check for non-existing readMethod 
Object value = new PropertyDescriptor("name", Person.class).getReadMethod().invoke(person); 

然而,也有很多擴展和簡化的java.beans API庫。 Commons BeanUtils是一個衆所周知的例子。在那裏,你只需要做:

Object value = PropertyUtils.getProperty(person, "name"); 

BeanUtils帶有其他方便的東西。即動態值轉換(對象到字符串,字符串到對象)以簡化用戶輸入的屬性設置。

+2

+1簡單的權利......完全正確;) – BalusC 2010-04-14 15:34:17

+0

非常感謝!這讓我免受字符串操作等! – guerda 2012-12-06 10:43:48

+1

很好的調用Apache的BeanUtils。使屬性的獲取/設置更容易,並處理類型轉換。 – 2012-12-18 03:43:15

4

的命名規則是行之有效的JavaBeans規範的一部分,由在java.beans包中的類支持。

15

可以使用Reflections框架,這

import static org.reflections.ReflectionUtils.*; 
Set<Method> getters = ReflectionUtils.getAllMethods(someClass, 
     withModifier(Modifier.PUBLIC), withPrefix("get"), withAnnotation(annotation)); 
3

您可以調用反射和也,排序時吸氣的值通過註釋

public class Student { 

private String grade; 

private String name; 

private String id; 

private String gender; 

private Method[] methods; 

@Retention(RetentionPolicy.RUNTIME) 
public @interface Order { 
    int value(); 
} 

/** 
* Sort methods as per Order Annotations 
* 
* @return 
*/ 
private void sortMethods() { 

    methods = Student.class.getMethods(); 

    Arrays.sort(methods, new Comparator<Method>() { 
     public int compare(Method o1, Method o2) { 
      Order or1 = o1.getAnnotation(Order.class); 
      Order or2 = o2.getAnnotation(Order.class); 
      if (or1 != null && or2 != null) { 
       return or1.value() - or2.value(); 
      } 
      else if (or1 != null && or2 == null) { 
       return -1; 
      } 
      else if (or1 == null && or2 != null) { 
       return 1; 
      } 
      return o1.getName().compareTo(o2.getName()); 
     } 
    }); 
} 

/** 
* Read Elements 
* 
* @return 
*/ 
public void readElements() { 
    int pos = 0; 
    /** 
    * Sort Methods 
    */ 
    if (methods == null) { 
     sortMethods(); 
    } 
    for (Method method : methods) { 
     String name = method.getName(); 
     if (name.startsWith("get") && !name.equalsIgnoreCase("getClass")) { 
      pos++; 
      String value = ""; 
      try { 
       value = (String) method.invoke(this); 
      } 
      catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 
       e.printStackTrace(); 
      } 
      System.out.println(name + " Pos: " + pos + " Value: " + value); 
     } 
    } 
} 

// /////////////////////// Getter and Setter Methods 

/** 
* @param grade 
* @param name 
* @param id 
* @param gender 
*/ 
public Student(String grade, String name, String id, String gender) { 
    super(); 
    this.grade = grade; 
    this.name = name; 
    this.id = id; 
    this.gender = gender; 
} 

/** 
* @return the grade 
*/ 
@Order(value = 4) 
public String getGrade() { 
    return grade; 
} 

/** 
* @param grade the grade to set 
*/ 
public void setGrade(String grade) { 
    this.grade = grade; 
} 

/** 
* @return the name 
*/ 
@Order(value = 2) 
public String getName() { 
    return name; 
} 

/** 
* @param name the name to set 
*/ 
public void setName(String name) { 
    this.name = name; 
} 

/** 
* @return the id 
*/ 
@Order(value = 1) 
public String getId() { 
    return id; 
} 

/** 
* @param id the id to set 
*/ 
public void setId(String id) { 
    this.id = id; 
} 

/** 
* @return the gender 
*/ 
@Order(value = 3) 
public String getGender() { 
    return gender; 
} 

/** 
* @param gender the gender to set 
*/ 
public void setGender(String gender) { 
    this.gender = gender; 
} 

/** 
* Main 
* 
* @param args 
* @throws IOException 
* @throws SQLException 
* @throws InvocationTargetException 
* @throws IllegalArgumentException 
* @throws IllegalAccessException 
*/ 
public static void main(String args[]) throws IOException, SQLException, IllegalAccessException, 
     IllegalArgumentException, InvocationTargetException { 
    Student student = new Student("A", "Anand", "001", "Male"); 
    student.readElements(); 
} 

}

輸出設置序列的順序

getId Pos: 1 Value: 001 
getName Pos: 2 Value: Anand 
getGender Pos: 3 Value: Male 
getGrade Pos: 4 Value: A