使用简单XML框架反序列化不可变的类

时间:2019-11-17 19:14:59

标签: java xml-deserialization simple-framework

假设我有一个这样的课程:

public class Measurement {
    /** The date and time at which the measurement was taken. */
    public final Date date;

    /** The measurement value. */
    public final float value;

    /** The name of the engineer who took the measurement. */
    public final String engineer;

    public Measurement(Date date, float value, String engineer) {
        super();
        this.date = date;
        this.value = value;
        this.engineer = engineer;
    }
}

每个Measurement实例都是不可变的。创建后,其成员无法修改。但是,可以创建一个新实例,其中某些值是从现有实例中复制的,而某些值则设置为不同。

如果事情变得更复杂,例如因为存在大量字段,并且大多数字段不是强制性的,所以构造函数将是私有的,而该类将带有一个builder类。 (实际上,实际代码更复杂;这只是一个最小的示例。)

现在,我可以很容易地添加一些SimpleXML批注,以将其序列化为XML,如下所示:

@Root(name="measurement")
@Default
public class Measurement {
    /** The date and time at which the measurement was taken. */
    @Attribute
    public final Date date;

    /** The measurement value. */
    @Attribute
    public final float value;

    /** The name of the engineer who took the measurement. */
    @Attribute
    public final String engineer;

    public Measurement(Date date, float value, String engineer) {
        super();
        this.date = date;
        this.value = value;
        this.engineer = engineer;
    }
}

然后将其序列化为:

<measurement date="2019-11-01 11:55:42.0 CET" value="42.0" engineer="Doe"/>

然后我将如何去反序列化生成的XML代码回到类?

1 个答案:

答案 0 :(得分:1)

执行此操作的官方方法似乎是constructor injection:设置最终成员的唯一方法是通过构造函数,构造函数为每个成员都有一个参数。因此,构造函数将如下所示:

public Measurement(@Attribute(name="date") Date date,
                   @Attribute(name="value") float value,
                   @Attribute(name="engineer") String engineer) {
    super();
    this.date = date;
    this.value = value;
    this.engineer = engineer;
}

据我所知,有必要在此处指定属性名称,即使它与参数相对应。

在示例中,构造函数是公共的。不确定这里需要什么,因为SimpleXML似乎依靠反射来找到正确的构造函数。