2016-03-10 3 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; 

} 

и избавиться от ваших геттеры/сеттеры

+0

нет, представьте, что у меня есть строка типа "student.address.city ​​" – 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 статически.

Смежные вопросы