<complexType name="BookShelf">
<sequence>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="newBook" type="string"/>
<element name="oldBook" type="string"/>
</choice>
</sequence>
</complexType>
JAXB将该属性生成为List<JAXBElement<String>>
。有没有什么方法可以生成ArrayList?
答案 0 :(得分:14)
ArrayList<E>
没有公开
不在的方法
List<E>
接口,所以有
你无能为力
你无法做到的ArrayList<E>
与任何其他List<E>
(实际上
有一个:
ArrayList.trimToSize()
,
谢谢@Joachim Sauer,但是
几乎没有必要)。ArrayList
?
ArrayList
是最多的
常用的List实现
无论如何,所以很有可能
JAXB实际上会返回一个
ArrayList
,它不会告诉你
所以(因为你不需要知道)。第40项包含您的建议 应该使用接口而不是 类作为参数类型。更多 一般来说,你应该赞成使用 接口而不是类 指对象。 如果合适的话 那么接口类型就存在了 参数,返回值,变量, 和字段都应该声明 使用界面类型。唯一的时间 你真的需要参考一个 对象的类是在你创建的时候 它与构造函数。为了做到这一点 具体,考虑的情况
Vector
,这是一个实现List
接口的。进入 打字的习惯:
// Good - uses interface as type
List<Subscriber> subscribers = new Vector<Subscriber>();
而不是:
// Bad - uses class as type!
Vector<Subscriber> subscribers = new Vector<Subscriber>();
[...]
来源:有效的Java,preview on SafariBooksOnline。
答案 1 :(得分:5)
默认情况下,该属性为List,底层实现为ArrayList。当然,您可以使用JAXB自定义来更改底层实现,或者使用自己的类具有ArrayList类型的属性(尽管出于其他答案中提到的原因,这很少是一个好主意)。
默认JAXB生成
给出您的XML Schema:
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<complexType name="BookShelf">
<sequence>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="newBook" type="string"/>
<element name="oldBook" type="string"/>
</choice>
</sequence>
</complexType>
</schema>
使用以下命令行:
xjc -d out your-schema.xsd
JAXB将生成以下类:
package generated;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "BookShelf", propOrder = {
"newBookOrOldBook"
})
public class BookShelf {
@XmlElementRefs({
@XmlElementRef(name = "newBook", type = JAXBElement.class),
@XmlElementRef(name = "oldBook", type = JAXBElement.class)
})
protected List<JAXBElement<String>> newBookOrOldBook;
public List<JAXBElement<String>> getNewBookOrOldBook() {
if (newBookOrOldBook == null) {
newBookOrOldBook = new ArrayList<JAXBElement<String>>();
}
return this.newBookOrOldBook;
}
}
自定义代
默认情况下,JAXB的属性类型为List,底层实现为ArrayList。如果您希望控制底层实现,可以使用外部绑定文件,如:
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jxb:bindings schemaLocation="f3.xsd">
<jxb:bindings node="//xs:complexType[@name='BookShelf']/xs:sequence/xs:choice">
<jxb:property collectionType="java.util.LinkedList"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
以下XJC致电:
xjc -d out -b binding.xml your-schema.xsd
改为获得以下课程:
package generated;
import java.util.LinkedList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "BookShelf", propOrder = {
"newBookOrOldBook"
})
public class BookShelf {
@XmlElementRefs({
@XmlElementRef(name = "oldBook", type = JAXBElement.class),
@XmlElementRef(name = "newBook", type = JAXBElement.class)
})
protected List<JAXBElement<String>> newBookOrOldBook = new LinkedList<JAXBElement<String>>();
public List<JAXBElement<String>> getNewBookOrOldBook() {
if (newBookOrOldBook == null) {
newBookOrOldBook = new LinkedList<JAXBElement<String>>();
}
return this.newBookOrOldBook;
}
}
使用您自己的课程:
您也可以使用自己的类与ArrayList类型的属性(尽管出于其他答案中提到的原因,这很少是个好主意。)
package com.example;
import java.util.ArrayList;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "BookShelf", propOrder = {
"newBookOrOldBook"
})
public class BookShelf {
@XmlElementRefs({
@XmlElementRef(name = "oldBook", type = JAXBElement.class),
@XmlElementRef(name = "newBook", type = JAXBElement.class)
})
protected ArrayList<JAXBElement<String>> newBookOrOldBook ;
public ArrayList<JAXBElement<String>> getNewBookOrOldBook() {
if (newBookOrOldBook == null) {
newBookOrOldBook = new ArrayList<JAXBElement<String>>();
}
return this.newBookOrOldBook;
}
}
更多信息:
答案 2 :(得分:1)
您无法更改API生成列表的事实。
但是,假设底层实现实际上产生了一个ArrayList,你总是可以将它转换为ArrayList:
ArrayList<JAXBElement<String>> arrayList =
(ArrayList<JAXBElement<String>>) list;
或者,如果它不是一个arraylist(即你尝试上面的例外...),你可以生成一个包含相同列表元素的新ArrayList。
ArrayList<JAXBElement<String>> arrayList =
new ArrayList<JAXBElement<String>>(list);
但是,一般情况下,您不需要执行任何操作:只要可以,就可以更好地对接口抽象进行编码而不是基础具体类。