从Modelclass层次结构的顶层调用setter



假设您有一个模型类层次结构,如

public class TopLevel {
private MiddleLevel middleLevel = null;
public TopLevel() {
middleLevel = new MiddleLevel();
}
public MiddleLevel getMiddleLevel() { return middleLevel; }
}
public class MiddleLevel {
private LowLevel lowLevel = null;
public MiddleLevel () {
lowLevel = new LowLevel();
}
public LowLevel getLowLevel() { return lowLevel; }
}
public class LowLevel {
private Value value = null;
public LowLevel() {
value = new Value();
}
public Value getValue() { return value; }
}
public class Value {
private String stringValue = "ItsAValue";
private String doubleValue = 1.0d;
private String integerValue = 4321;
public void setStringValue(String value) {
stringValue = value;
}
}

当然,还有其他具有不同属性的类。例如,这个层次结构是由Jaxb创建和实例化的。

现在,我想在value类中设置一个值。当然,我可以执行类似的操作:

TopLevel topLevel = new TopLevel();
topLevel.getMiddleLevel().getLowLevel().getValue().setStringValue("NewValue");

有没有一种方法可以简化或概括这一点,例如,能够通过所有这些类对象调用"路径"来在内部深处设置一个值?这里有一些伪代码,我的意思是:

public class Anotherclass {
public static void main(String[] args) {
TopLevel topLevel = new TopLevel();
setStringValueByPath("topLevel/middleLevel/lowLevel/value/stringValue", "newValue");
setDoubleValueByPath("topLevel/middleLevel/lowLevel/value/doubleValue", 5.0d);
setIntegerValueByPath("topLevel/middleLevel/lowLevel/value/integerValue", 1234);
}
}

非常感谢

Alex

好的,如果有人感兴趣,我想我找到了一个我正在寻找的解决方案:

一种基于Java.reflection的递归方法:

public class ReflectionSetter {
private static List<Field> getFields(Object object) {
List<Field> fields = new ArrayList<>();
fields.addAll(Arrays.asList(object.getClass().getDeclaredFields()));
return fields;
}
private static Field hasField(Object object, String fieldName) {
for (Field f : getFields(object)) {
if (f.getName().equalsIgnoreCase(fieldName)) return f;
}
return null;
}
public static void setValue(Object object, String path, String newValue) throws IllegalArgumentException, IllegalAccessException {
if (path.contains("/")) {
int pos = path.indexOf('/');
String first = path.substring(0, pos);
String rest = path.substring(pos+1);
Field f = ReflectionSetter.hasField(object, first);
if (null == f) throw new IllegalArgumentException("Path not found: " + path);
f.setAccessible(true);
Object obj = f.get(object);
setValue(obj, rest, newValue);
} else {
Field f = ReflectionSetter.hasField(object, path);
if (f == null) throw new IllegalArgumentException("Field not found: " + path);
// if found -> set value
f.setAccessible(true);
f.set(object, newValue);
}
}
}

现在,您可以通过路径设置一个值。用法:

TopLevel topLevel = new TopLevel();
ReflectionSetter.setValue(topLevel, "middleLevel/lowLevel/value/myValue", "NewValue");

实现这一点的理想有效方法是,通过更多地关注降低代码复杂性,同时提高代码可读性,您应该关注设计模式,可能类似于访问者模式。

访问者模式最常见的用例之一是,由于算法和数据结构的分离,它能够在不修改所述结构的情况下向现有对象结构添加新操作。

进入">我想看看问题中所指出的基于字符串的方法"的阶段。Apache公共库提供了一种名为JxPath的东西。如果您尝试查看JxPathref.apache.jx.path ,则不确定

它提供了一个名为XPath的表达式语言的简单解释器。JXPath将XPath表达式应用于各种对象的图

从你的问题中挑选一个例子:

TopLevel topLevel = new TopLevel();
JXPathContext context = JXPathContext.newContext(topLevel);
context.setValue("middleLevel/lowLevel/value/stringValue", "newStringValue");

最新更新