2016-03-10 53 views
0

我可以用下面的語法訪問實例字段: student.address.city訪問(私有)成員點號分隔字符串

public class Student { 
    private Address address; 
    //getters&setters 
} 

public class Address { 
    private String town; 
    private String street; 
    private String city; 
    //getters&setters 
} 

我覺得能以某種方式使用反射來完成。 基本上,我需要這樣的東西:

String city = getPropertyValue("student.address.city", student); 

像JS我們可以訪問對象的屬性。

+0

可以很容易地發佈一些代碼...... –

+0

感謝** talex **和** Adowrath **。通過使用你的答案,問題解決了。 – romanvintonyak

+0

還有一個org.apache.commons.beanutils.PropertyUtils.getNestedProperty()專用的方法。 – romanvintonyak

回答

2

還有一個名爲org.apache.commons.beanutils.PropertyUtils.getNestedProperty()專用的方法。

+0

就我個人而言,我建議不要這樣做,因爲它涉及到僅僅爲了一個目的而包括整個圖書館。請考慮選擇其他答案之一。 – Adowrath

-1

是的,使您的字段/屬性public例如

public class Student { 
    public Address address; 

} 

public class Address { 
    public String town; 
    public String street; 
    public String city; 

} 

,並擺脫掉你的getter/setter方法

+0

不,假設我有一個像「student.address」的字符串。城市「 – romanvintonyak

2

Java不支持這種語法默認。但你可以輕鬆地自己做。
首先解析您想要訪問屬性的String

String[] path = "a.b.x".split("\\."); 

注意:您需要因爲String#split作品與Regular Expressions,並.RegEx作爲一個特殊的通配符處理逃脫.字符。

之後,您可以使用部分在path找到這樣的值:

Object o = ... // An Object to start with, "Student" in your 
       // example (don't make it Student o = ... though!) 
for(String part : path){ 
    o = resolveField(o, part) // Overwrites with the new object 
} 

最終的結果保存在o

所有反射的方法發生resolveField

Object resolveField(Object root, String fieldName) throws NoSuchFieldException, IllegalAccessException { 
    Class<?> clazz = root.getClass(); 
    Field field = clazz.getDeclaredField(fieldName); 
    field.setAccessible(true); // Lets you work with private fields. You do not 
           // have to restore the old value as it's only 
           // for the Field object, not for the field itself 
    return field.get(root); 
} 

注意,有一些庫包含此功能已經,例如Java Expressions Library,雖然它遠不止於此。

3

這實際上使用getDeclaredField方法非常簡單。

但是,在開始時提供student作爲第一個參數,因爲Java不知道您正在引用哪個student-object

void someOtherMethod() { 
    // ... 
    Student student = // ... 
    String city = getPropertyValue(student, "address.city"); 
    // ... 
} 

@SuppressWarnings("unchecked") 
public static <T> T getPropertyValue(Object obj, String string) { 
    Object ret = obj; 
    String[] parts = string.split("\\."); 

    for(String field : parts) { 
     try { 
      Class<?> clazz = ret.getClass(); 
      Field f = clazz.getDeclaredField(field); 
      f.setAccessible(true); 
      ret = f.get(ret); 
     } catch(NoSuchFieldException | SecurityException | IllegalAccessException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    return (T) ret; 
} 

充分利用#getPropertyValue方法static這樣你就可以與其他地方引用這一切的時候,甚至import它靜態。