Java JAXB可以生成ArrayList而不是List吗?
JAXB将属性生成为Java JAXB可以生成ArrayList而不是List吗?,java,collections,jaxb,arraylist,Java,Collections,Jaxb,Arraylist,JAXB将属性生成为列表。有没有办法将其生成为ArrayList?为什么,这对您有什么好处? 没有公开的 不在列表中的方法 接口,所以有 这件事你无能为力 ArrayList您无法执行的操作 与任何其他列表(实际上 有一个: , 谢谢@Joachim Sauer,但它是 几乎不需要) 对于API来说,这是一种糟糕的做法 接受或返回实现 类型而不是基础类型 接口。我建议你去 追随 Sun Java教程和/或阅读 (你会知道他在干什么 谈论,这是下面引用的来源)了解更多关于 集合框架和接口 用法 谁
列表
。有没有办法将其生成为ArrayList?为什么,这对您有什么好处?
ArrayList
您无法执行的操作
与任何其他列表
(实际上
有一个:
,
谢谢@Joachim Sauer,但它是
几乎不需要)ArrayList
?
ArrayList
是最
常用列表实现
不管怎样,这样的可能性很高
JAXB实际上将返回一个
ArrayList
,它不会告诉你
所以(因为你不需要知道)Vector
,这是一种实现
列表
界面的。上车
打字的习惯:
//良好-使用接口作为类型
列表订阅者=新向量();
与此相反:
//错误-使用类作为类型!
向量订阅者=新向量();
[……]
来源:有效的Java,。您不能更改API生成列表的事实 但是,假设基础实现实际生成ArrayList,则始终可以将其强制转换为ArrayList:
// Bad - uses class as type!
Vector<Subscriber> subscribers = new Vector<Subscriber>();
ArrayList ArrayList=
(ArrayList)列表;
或者,如果它不是arraylist(即,尝试上述操作时出现异常…),则可以生成一个包含列表中相同元素的新arraylist
ArrayList<JAXBElement<String>> arrayList =
(ArrayList<JAXBElement<String>>) list;
ArrayList ArrayList=
新ArrayList(列表);
但是,一般来说,您不需要这样做:只要有可能,最好针对接口抽象而不是底层具体类进行编码。默认情况下,属性将是一个列表,底层实现将是一个ArrayList。当然,您可以使用JAXB定制来更改底层实现,或者使用您自己的具有ArrayList类型属性的类(尽管出于其他答案中提到的原因,这很少是一个好主意) 默认JAXB生成 给定您的XML架构:
ArrayList<JAXBElement<String>> arrayList =
new ArrayList<JAXBElement<String>>(list);
JAXB将生成以下类:
xjc -d out your-schema.xsd
改为获取以下类:
xjc -d out -b binding.xml your-schema.xsd
生成包;
导入java.util.LinkedList;
导入java.util.List;
导入javax.xml.bind.JAXBElement;
导入javax.xml.bind.annotation.XmlAccessType;
导入javax.xml.bind.annotation.XmlAccessorType;
导入javax.xml.bind.annotation.xmlementref;
导入javax.xml.bind.annotation.xmlementrefs;
导入javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name=“BookShelf”,proporter={
“新图书”
})
公共类书架{
@XmlElementRefs({
@XmlElementRef(name=“oldBook”,type=JAXBElement.class),
@xmlementref(name=“newBook”,type=JAXBElement.class)
})
受保护列表newBookOrOldBook=newlinkedlist();
公共列表getNewBookOrOldBook(){
if(newBookOrOldBook==null){
newBookOrOldBook=newlinkedlist();
}
归还这个.newBookOrOldBook;
}
}
使用自己的类:
您还可以将自己的类与ArrayList类型的属性一起使用(尽管出于其他答案中提到的原因,这很少是一个好主意)
package.com.example;
导入java.util.ArrayList;
导入javax.xml.bind.JAXBElement;
导入javax.xml.bind.annotation.XmlAccessType;
导入javax.xml.bind.annotation.XmlAccessorType;
导入javax.xml.bind.annotation.xmlementref;
导入javax.xml.bind.annotation.xmlementrefs;
导入javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name=“BookShelf”,proporter={
“新图书”
})
公共类书架{
@XmlElementRefs({
@XmlElementRef(name=“oldBook”,type=JAXBElement.class),
@xmlementref(name=“newBook”,type=JAXBElement.class)
})
受保护的ArrayList newBookOrOldBook;
公共ArrayList getNewBookOrOldBook(){
if(newBookOrOldBook==null){
newBookOrOldBook=newarraylist();
}
归还这个.newBookOrOldBook;
}
}
有关更多信息:
实例,几乎不应该进行演员扮演。@Sean Patrick Floyd-对我来说这是一个明确的(+1),因为(1)它给出了问题的解决方案,(2)我不知道实际的需求
<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
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;
}
}
<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 -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;
}
}
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;
}
}