假设我们有一个班级structure
:
class Street {
String name;
List<Building> buildings;
}
class Building {
String number;
int floors;
List<Apartment> apartments;
}
class Apartment {
String owner;
}
runtime
我对上面的结构一无所知。我所拥有的只是一个object
和一个String
参数,其中包含有关我必须分配的属性的数据。
例如String "buildings.0/floors#5"
意味着我必须将列表中第一个Building的floors属性分配给5.而String "buildings.0/apartments.1/owner#Luke"
意味着我必须为“Luke”分配所有者属性第二栋公寓位于第一栋楼的公寓中。
我知道如何使用反射分配属性。但是,如果我们必须分配属性本身的属性呢?是否可以实现这样的逻辑?
答案 0 :(得分:1)
我刚刚根据你的结构做了一个简单的解决方案。这有很多要添加(NullPointerException,OutOfBounds,...)但是为了正确输入,你有一个正确的答案。
然后你只需要方法,一个设置值,一个从列表中获取实例。两者都需要使用反射。
public Object getListItem(Object o, String name, int index) throws Exception{
return ((List)o.getClass().getDeclaredField(name).get(o)).get(index);
}
public void setValue(Object o, String name, Object value) throws Exception{
o.getClass().getDeclaredField(name).set(o, value);
}
就像说的那样,没有检查,我做的很简单,因为我是从头开始做的。
然后,只需要根据/
解析String(再次,不检查)来找到每个[变量/值]块。并找到这是什么类型:
#
,则为归属.
,则这是列表中的getter 所以这应该是这样的。
public void init(Object o, String pattern) throws Exception{
String[] array = pattern.split("/");
for(String s : array){
if(s.contains("#")){
String[] param = s.split("\\#");
setValue(o, param[0], param[1]);
} else {
String[] list = s.split("\\.");
o = getListItem(o, list[0], Integer.parseInt(list[1]));
}
}
}
以下是您可以在ideone here
上找到的示例的输出那将输出
[Street] Foo [
[Building] 1 1[[Apartment] null, [Apartment] null],
[Building] 2 2[[Apartment] null, [Apartment] null, [Apartment] null, [Apartment] null],
[Building] 3 1[[Apartment] null, [Apartment] null]]
[Street] Foo [
[Building] 1 1[[Apartment] null, [Apartment] null],
[Building] 2 3[[Apartment] null, [Apartment] null, [Apartment] null, [Apartment] null],
[Building] 3 1[[Apartment] null, [Apartment] null]]
[Street] Foo [
[Building] 1 1[[Apartment] null, [Apartment] null],
[Building] 2 3[[Apartment] null, [Apartment] null, [Apartment] null, [Apartment] null],
[Building] 3 1[[Apartment] null, [Apartment] John]]
答案 1 :(得分:1)
如果您的类遵循JavaBeans约定(标准getter和setter封装字段),则可以使用Introspector
以及依赖它的几个框架。
我最喜欢的例子是Spring's BeanWrapper technology,它允许你编写如下代码:
BeanWrapper bw = new BeanWrapperImpl(street);
bw.setPropertyValue("buildings[0].appartments[1].owner", "luke");