繁体   English   中英

通过 YAML 文件加载基于 object 的抽象 class

[英]Loading an abstract class based object by YAML file

我想加载 object ,其中包含基于 yaml 文件中的抽象 class 的对象数组列表。 我收到此错误消息:

线程“LWJGL 应用程序”中的异常无法为 JavaBean=com.myyaml.test.ImplementationOfExampleClass@7a358cc1 创建 property=arrayListOfAbstractObjects

在“阅读器”第 1 行第 1 列中:dummyLong: 1 ^

java.lang.InstantiationException 在“阅读器”,第 3 行,第 3 列:-dummyFloat:444 ^

YAML 文件

dummyLong: 1
arrayListOfAbstractObjects:
  - dummyFloat: 444
  - dummyDouble: 123

Java 类:

public abstract class ExampleClass {
    protected ArrayList<AbstractClass> arrayListOfAbstractObjects;
    protected long dummyLong = 111;
    
    public ExampleClass() {
    }

    public void setArrayListOfAbstractObjects(ArrayList<AbstractClass> arrayListOfAbstractObjects) {
        this.arrayListOfAbstractObjects = arrayListOfAbstractObjects;
    }

    public void setDummyLong(long dummyLong) {
        this.dummyLong = dummyLong;
    }
}
public class ImplementationOfExampleClass extends ExampleClass {
    
    public ImplementationOfExampleClass() {
    }
}
public abstract class AbstractClass {
    private int dummyInt = 22;
    
    public AbstractClass() {
    }

    public void setDummyInt(int dummyInt) {
        this.dummyInt = dummyInt;
    }
}
public class FirstImplementationOfAbstractClass extends AbstractClass {
    float dummyFloat = 111f;
    
    public FirstImplementationOfAbstractClass() {
    }

    public void setDummyFloat(float dummyFloat) {
        this.dummyFloat = dummyFloat;
    }
}
public class SecondImplementationOfAbstractClass extends AbstractClass {
    double dummyDouble = 333f;
    
    public SecondImplementationOfAbstractClass() {
    }

    public void setDummyDouble(double dummyDouble) {
        this.dummyDouble = dummyDouble;
    }
}

我的猜测是 yaml 不知道要使用哪种抽象 class 实现。 FirstImplementationOfAbstractClass 或 SecondImplementationOfAbstractClass。 是否可以通过 yaml 使用此类加载 object ?

这只有在您告诉 YAML 处理器您要在 YAML 端实例化哪个 class 时才有可能。 您可以使用标签执行此操作:

dummyLong: 1
arrayListOfAbstractObjects:
  - !first
    dummyFloat: 444
  - !second
    dummyDouble: 123

然后,您可以指示您的 YAML 处理器根据其标签正确处理项目。 例如使用 SnakeYAML,你会做

class MyConstructor extends Constructor {
    public MyConstructor() {
        this.yamlConstructors.put(new Tag("!first"), new ConstructFirst());
        this.yamlConstructors.put(new Tag("!second"), new ConstructSecond());
    }

    private class ConstructFirst extends AbstractConstruct {
        public Object construct(Node node) {
            // raw values, as if you would have loaded the content into a generic map.
            final Map<Object, Object> values = constructMapping(node);
            final FirstImplementationOfAbstractClass ret =
                    new FirstImplementationOfAbstractClass();
            ret.setDummyFloat(Float.parseFloat(values.get("dummyFloat").toString()));
            return ret;
        }
    }

    private class ConstructSecond extends AbstractConstruct {
        public Object construct(Node node) {
            final Map<Object, Object> values = constructMapping(node);
            final SecondImplementationOfAbstractClass ret =
                    new SecondImplementationOfAbstractClass();
            ret.setDummyFloat(Double.parseDouble(values.get("dummyFloat").toString()));
            return ret;
        }
    }
}

注意:加载内容时可以更智能,避免toString ,直接处理节点内容; 为了方便演示,我使用了一个愚蠢的实现。

然后,您使用此构造函数:

Yaml yaml = new Yaml(new MyConstructor());
ExampleClass loaded = yaml.loadAs(input, ImplementationOfExampleClass.class);

节点 class 是一种 YAML 文件转换为 Java 数据 object。 我在调试器下发现它包含字段ArrayList<E>值。 其中包含带有 YAML 文件字段的 NodeTuple(例如 dummyFloat)。 所以我必须在constructMapping(node)方法中自己转换每个字段,然后在构造的object 上将它们设置在例如ConstructFirst.construct(Node node)中。

编辑:

所以我必须在constructMapping(node)方法中自己转换每个字段,然后在构造的object 上将它们设置在例如ConstructFirst.construct(Node node)中。

需要将参数节点转换为 MappingNode。 该方法继承自 BaseConstructor.constructMapping(MappingNode 节点)。 Flyx 没有添加该演员表,我不知道从哪里得到它。 感谢帮助。 现在它起作用了。 但我仍然在与嵌套抽象类作斗争。 也许我需要帮助,但我会努力处理好自己。

此链接也可能有帮助: Polymorphic collections in SnakeYaml

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM