我可以通过以下语法访问实例字段: 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 :(得分:4)
还有一个名为org.apache.commons.beanutils.PropertyUtils.getNestedProperty()的方法专用于此。
答案 1 :(得分: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
静态引用它。
答案 2 :(得分: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 :(得分:-1)
是的,请填写您的字段/属性public
,例如
public class Student {
public Address address;
}
public class Address {
public String town;
public String street;
public String city;
}
并摆脱你的getter / setter