首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从模型类层次结构的顶层调用setter

从模型类层次结构的顶层调用setter
EN

Stack Overflow用户
提问于 2020-02-23 19:45:59
回答 2查看 53关注 0票数 0

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

代码语言:javascript
复制
    public class TopLevel {
        private MiddleLevel middleLevel = null;

        public TopLevel() {
            middleLevel = new MiddleLevel();
        }

        public MiddleLevel getMiddleLevel() { return middleLevel; }
    }
代码语言:javascript
复制
    public class MiddleLevel {
        private LowLevel lowLevel = null;

        public MiddleLevel () {
            lowLevel = new LowLevel();
        }

        public LowLevel getLowLevel() { return lowLevel; }
    }
代码语言:javascript
复制
    public class LowLevel {
        private Value value = null;

        public LowLevel() {
            value = new Value();
        }

        public Value getValue() { return value; }
    }
代码语言:javascript
复制
    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-class中设置一个值。当然,我可以执行下面这样的代码:

代码语言:javascript
复制
    TopLevel topLevel = new TopLevel();
    topLevel.getMiddleLevel().getLowLevel().getValue().setStringValue("NewValue");

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

代码语言:javascript
复制
    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);
        }

    }

非常感谢

亚历克斯

EN

回答 2

Stack Overflow用户

发布于 2020-02-23 23:31:24

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

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

代码语言:javascript
复制
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);
        }
    }
}

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

代码语言:javascript
复制
    TopLevel topLevel = new TopLevel();
    ReflectionSetter.setValue(topLevel, "middleLevel/lowLevel/value/myValue", "NewValue");
票数 0
EN

Stack Overflow用户

发布于 2020-02-23 23:36:06

要做到这一点,一个理想的有效方法是,通过更多地关注降低代码复杂性,同时提高代码的可读性,你应该考虑设计模式,可能是类似于visitor模式。

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

进入一个阶段,“不,我想看看基于字符串的方法,正如所指出的问题”。Apache commons库提供了名为JxPath的东西。不确定您是否尝试查看JxPath ref.apache.jx.path

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

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

代码语言:javascript
复制
TopLevel topLevel = new TopLevel();
JXPathContext context = JXPathContext.newContext(topLevel);
context.setValue("middleLevel/lowLevel/value/stringValue", "newStringValue");
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60361864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档