java 如何克隆 JAXB 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/930840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:25:03  来源:igfitidea点击:

How Do I Clone A JAXB Object

javajaxb

提问by Shane C. Mason

I have some jaxb objects (instantiated from code generated from xsd by jaxb) that I need to clone. The Jaxb class does not appear to provide an interface for doing this easily. I can not hand edit the class and can not extend it - so I need to create a helper/utility method to do this. What is the best approach?

我有一些需要克隆的 jaxb 对象(从 jaxb 从 xsd 生成的代码中实例化)。Jaxb 类似乎没有提供用于轻松执行此操作的接口。我无法手动编辑该类并且无法扩展它 - 所以我需要创建一个帮助器/实用程序方法来做到这一点。最好的方法是什么?

采纳答案by ykaganovich

Given the purpose of JAXB, I think the easiest way would be to marshall your object to XML and unmarshall it back.

鉴于 JAXB 的目的,我认为最简单的方法是将您的对象编组为 XML,然后将其解组。

Lots more discussions on Google.

更多关于Google 的讨论。

JAXB FAQ suggestsbeanlib.

JAXB FAQ建议使用beanlib

There's also some discussion(as well as a link to download) of a Cloneable plugin under jaxb2-commons, although I can't find any reference on the project page.

还有一些关于jaxb2-commons 下的 Cloneable 插件的讨论(以及下载链接),尽管我在项目页面上找不到任何参考。

回答by Boris

You should try cc-xjc, which is available on sourceforge. One of its features is to generate clone() and copy-constructors.

您应该尝试cc-xjc,它在 sourceforge 上可用。它的功能之一是生成 clone() 和复制构造函数。

回答by lexicore

You can use the Copyable plugin. It generates deep copy/clone methods (which can be even customized with strategies).

您可以使用Copyable 插件。它生成深度复制/克隆方法(甚至可以使用策略自定义)。

回答by Lukas Eder

I've run benchmarks on various solutions for cloning a JAXB object. Here are some results:

我已经对克隆 JAXB 对象的各种解决方案运行了基准测试。以下是一些结果:

  1. Using mofokom's xjc-clone pluginseems to be the fastest solution. It just lets all your generated artefacts implement Cloneableand publicly overrides Object.clone(). Unfortunately, this hasn't made it into Maven central (yet).

  2. Generating Serializableartefacts and serialising / deserialising them to a dummy stream is 10x slower than using Java's cloning mechanisms:

    public <T extends Serializable> T clone(T jaxbObject) {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      ObjectOutputStream o = new ObjectOutputStream(out);
      o.writeObject(jaxbObject);
      o.flush();
    
      ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
      ObjectInputStream i = new ObjectInputStream(in);
      return (T) i.readObject();
    }
    
  3. Marshalling / Unmarshalling the JAXB objects is again 5x slower than serialising / deserialising them. This is what ykaganovich'ssolution suggests:

    public <T extends Serializable> T clone(T jaxbObject) {
      StringWriter xml = new StringWriter();
      JAXB.marshal(jaxbObject, xml);
      StringReader reader = new StringReader(xml.toString());
      return JAXB.unmarshal(reader, jaxbObject.getClass());
    }
    
  1. 使用mofokom 的 xjc-clone 插件似乎是最快的解决方案。它只是让您生成的所有人工制品实现Cloneable并公开覆盖Object.clone(). 不幸的是,这还没有进入 Maven 中心(还没有)。

  2. 生成Serializable人工制品并将它们序列化/反序列化为虚拟流比使用 Java 的克隆机制慢 10 倍:

    public <T extends Serializable> T clone(T jaxbObject) {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      ObjectOutputStream o = new ObjectOutputStream(out);
      o.writeObject(jaxbObject);
      o.flush();
    
      ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
      ObjectInputStream i = new ObjectInputStream(in);
      return (T) i.readObject();
    }
    
  3. 编组/解组 JAXB 对象再次比序列化/反序列化它们慢 5 倍。这就是ykaganovich 的解决方案所建议的:

    public <T extends Serializable> T clone(T jaxbObject) {
      StringWriter xml = new StringWriter();
      JAXB.marshal(jaxbObject, xml);
      StringReader reader = new StringReader(xml.toString());
      return JAXB.unmarshal(reader, jaxbObject.getClass());
    }
    

回答by Martin Vysny

We have used the jaxb2-basics plugin - it is available in Maven repo, adds only a single dependency and can also be used to generate other useful stuff: equals, hashCode, toString, default values etc. Please see this link for details: http://pragmaticintegrator.wordpress.com/2012/11/20/cloning-a-jaxb-object/

我们使用了 jaxb2-basics 插件 - 它在 Maven 仓库中可用,仅添加一个依赖项,也可用于生成其他有用的东西:equals、hashCode、toString、默认值等。请参阅此链接了解详细信息:http ://pragmaticintegrator.wordpress.com/2012/11/20/cloning-a-jaxb-object/

回答by gil.fernandes

This is an old thread, but I had to create cloneable JAXB domain objects too and I think that marshalling - unmarshalling is not the best solution for sure.

这是一个旧线程,但我也必须创建可克隆的 JAXB 域对象,我认为编组 - 解组肯定不是最好的解决方案。

Ideally you should copy the objects in memory using generated clone methods. There is a Maven plugin (maven-jaxb2-plugin) which you can use for this purpose.

理想情况下,您应该使用生成的克隆方法复制内存中的对象。有一个 Maven 插件 ( maven-jaxb2-plugin) 可用于此目的。

These are the relevant section in my Maven pom.xml file:

这些是我的 Maven pom.xml 文件中的相关部分:

<dependency>
    <groupId>org.jvnet.jaxb2_commons</groupId>
    <artifactId>jaxb2-basics</artifactId>
    <version>0.11.1</version>
</dependency>

...

...

<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <extension>true</extension>
        <schemaDirectory>${basedir}/src/main/xsd</schemaDirectory>
        <bindingDirectory>${basedir}/src/main/xjb</bindingDirectory>
        <args>
            <arg>-Xcopyable</arg>
        </args>
        <plugins>
            <plugin>
                <groupId>org.jvnet.jaxb2_commons</groupId>
                <artifactId>jaxb2-basics</artifactId>
                <version>1.11.1</version>
            </plugin>
        </plugins>
    </configuration>
</plugin>

Note the -Xcopyableargument which generates the clone method inside of all objects.

注意-Xcopyable参数,它在所有对象中生成 clone 方法。

If you use

如果你使用

mvn clean install

for building the project this will generate the domain classes with a clone implementation.

为了构建项目,这将生成具有克隆实现的域类。

This is an extract of the clone related methods in one of the domain classes:

这是域类之一中与克隆相关的方法的摘录:

public Object clone() {
    return copyTo(createNewInstance());
}

public Object copyTo(Object target) {
    final CopyStrategy2 strategy = JAXBCopyStrategy.INSTANCE;
    return copyTo(null, target, strategy);
}

You can find the sources and samples of the jaxb2 basics project on this page:

您可以在此页面上找到 jaxb2 基础项目的源代码和示例:

https://github.com/highsource/jaxb2-basics/wiki/Sample-Projects

https://github.com/highsource/jaxb2-basics/wiki/Sample-Projects

The releases with useful examples can be downloaded from here:

可以从这里下载带有有用示例的版本:

https://github.com/highsource/jaxb2-basics/releases

https://github.com/highsource/jaxb2-basics/releases