为什么JAXB不为列表生成setter?

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

 /** * 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方法中build议的方法有什么优点吗?

这是我的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> 

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

devise注意事项 – List属性没有setter方法。 getter通过引用返回List。 可以使用在java.util.List上定义的适当方法将项目添加到由getter方法返回的List中。 JAXB 1.0中这个devise的基本原理是使实现能够封装列表,并能够在列表中添加或删除内容时执行检查。

因此,如果List的实现被覆盖了add / remove来执行validation,那么用(例如)一个ArrayListreplace这个“special”List将会失败这些检查。

链接: 没有设置列表

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

正如引言所说,在使用getter方法时没有setter,所以如果不存在,可以确保列表的新实例被初始化。

之后,当你必须添加或删除任何你将不得不使用

 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> 

同意Patrick的关注。 如果我直接对生成的java类进行编码,我很乐意提供,但是我使用的是一种内省的工具,它需要一个setter或一个可直接访问的成员。 从https://github.com/highsource/jaxb2-basics/wiki/JAXB2-Setters-Plugin使用插件到XJC并向wsimport添加-B-Xsetter参数;