Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JAXB可以生成ArrayList而不是List吗?_Java_Collections_Jaxb_Arraylist - Fatal编程技术网

Java JAXB可以生成ArrayList而不是List吗?

Java JAXB可以生成ArrayList而不是List吗?,java,collections,jaxb,arraylist,Java,Collections,Jaxb,Arraylist,JAXB将属性生成为列表。有没有办法将其生成为ArrayList?为什么,这对您有什么好处? 没有公开的 不在列表中的方法 接口,所以有 这件事你无能为力 ArrayList您无法执行的操作 与任何其他列表(实际上 有一个: , 谢谢@Joachim Sauer,但它是 几乎不需要) 对于API来说,这是一种糟糕的做法 接受或返回实现 类型而不是基础类型 接口。我建议你去 追随 Sun Java教程和/或阅读 (你会知道他在干什么 谈论,这是下面引用的来源)了解更多关于 集合框架和接口 用法 谁

JAXB将属性生成为
列表
。有没有办法将其生成为ArrayList?

为什么,这对您有什么好处?
  • 没有公开的 不在列表中的方法 接口,所以有 这件事你无能为力
    ArrayList
    您无法执行的操作 与任何其他
    列表
    (实际上 有一个: , 谢谢@Joachim Sauer,但它是 几乎不需要)
  • 对于API来说,这是一种糟糕的做法 接受或返回实现 类型而不是基础类型 接口。我建议你去 追随 Sun Java教程和/或阅读 (你会知道他在干什么 谈论,这是下面引用的来源)了解更多关于 集合框架和接口 用法
  • 谁说基本清单 实现不是
    ArrayList
    ArrayList
    是最 常用列表实现 不管怎样,这样的可能性很高 JAXB实际上将返回一个
    ArrayList
    ,它不会告诉你 所以(因为你不需要知道)
  • 第52项:通过接口引用对象(摘录) 第40项包含您需要的建议 应该使用接口,而不是 类作为参数类型。更多 一般来说,你应该倾向于使用 接口,而不是类 引用对象如果合适 接口类型存在,则 参数、返回值、变量、, 和字段都应该声明 使用接口类型。唯一一次 你真的需要参考 对象的类是在您创建 它是一个构造函数。做这个 混凝土,考虑的情况
    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;
    }
    }
    
    有关更多信息:


    为什么?JAXB根据该模式生成了一种API。API不应包含具体的类。ArrayList只有一个比List多的公共方法:trimToSize(),这对您来说是必需的吗?顺便说一下:生成的代码在lazy getter中创建了一个ArrrayList实例。这是一个经典的+1/-1帖子。在技术方面,分享这一点很好,但你应该a)更加强调这是一种糟糕的做法(也许用“不应该”替换“不应该”来代替“不应该”)和b)如果没有检查
    实例,几乎不应该进行演员扮演。@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;
        }
    
    }