为什么 JAXB 不为列表生成 setters

2022-08-31 15:27:53

当我从 XSD 生成 JAXB 类时,带有 的元素会为它们生成一个 getter 方法,但没有 setter 方法,如下所示:maxOccurs="unbounded"

/**
 * Gets the value of the element3 property.
 * 
 * <p>
 * This accessor method returns a reference to the live list,
 * not a snapshot. Therefore any modification you make to the
 * returned list will be present inside the JAXB object.
 * This is why there is not a <CODE>set</CODE> method for the element3 property.
 * 
 * <p>
 * For example, to add a new item, do as follows:
 * <pre>
 *    getElement3().add(newItem);
 * </pre>
 * 
 * 
 * <p>
 * Objects of the following type(s) are allowed in the list
 * {@link Type }
 * 
 * 
 */
public List<Type> getElement3() {
    if (element3 == null) {
        element3 = new ArrayList<Type>();
    }
    return this.element3;
}

方法注释清楚地表明了如何使用它,但我的问题如下:
为什么JAXB不按照Java Beans规则生成一个setter?我知道我可以自己编写 setter 方法,但是生成的 getter 方法中建议的方法有什么优势吗?

这是我的 XSD:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.example.org/DoTransfer/" targetNamespace="http://www.example.org/DoTransfer/">

    <element name="CollectionTest" type="tns:CollectionTest"></element>

    <complexType name="CollectionTest">
        <sequence>
            <element name="element1" type="string" maxOccurs="1" minOccurs="1"></element>
            <element name="element2" type="boolean" maxOccurs="1" minOccurs="1"></element>
            <element name="element3" type="tns:type" maxOccurs="unbounded" minOccurs="1" nillable="true"></element>
        </sequence>
    </complexType>


    <complexType name="type">
        <sequence>
            <element name="subelement1" type="string" maxOccurs="1" minOccurs="1"></element>
            <element name="subelement2" type="string" maxOccurs="1" minOccurs="0"></element>
        </sequence>
    </complexType>
</schema>

答案 1

以下是 JAXB 规范的理由 - 第 60 页。

设计说明 – List 属性没有 setter 方法。getter 通过引用返回 List。可以使用 java.util.List 上定义的相应方法将项添加到 getter 方法返回的 List 中。JAXB 1.0 中此设计的基本原理是使实现能够包装列表,并能够在列表中添加或删除内容时执行检查。

因此,如果 List 的实现覆盖了 add/remove 以执行验证,则用 ArrayList 替换该“特殊”列表(例如)将破坏这些检查。


答案 2

链接 : 列表没有设置器

getter 方法中的代码可确保创建 List。没有相应的 setter,这意味着列表元素的所有添加或删除都必须在“实时”列表中进行。

正如引用所说,没有 setter,因为当您使用 getter 方法时,它确保在不存在时初始化列表的新实例。

之后,当您必须添加或删除必须使用的任何内容时

getElement3().add(Type);

更新:编组列表和空列表的区别null

列表所在的位置示例null

@XmlRootElement(name = "list-demo")
public class ListDemo {

    @XmlElementWrapper(name = "list")
    @XmlElement(name = "list-item")
    private List<String> list;

}

输出将为

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<list-demo/>

列表为的示例

@XmlRootElement(name = "list-demo")
public class ListDemo {

    @XmlElementWrapper(name = "list")
    @XmlElement(name = "list-item")
    private List<String> list = new ArrayList<String>();

}

输出将为:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<list-demo>
    <list/>
</list-demo>

推荐