Java JAXB 2 的 ObjectFactory 类有什么意义?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/953723/
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
What's the point of JAXB 2's ObjectFactory classes?
提问by Andrew Coleson
I'm new to using JAXB, and I used JAXB 2.1.3's xjc to generate a set of classes from my XML Schema. In addition to generating a class for each element in my schema, it created an ObjectFactory class.
我是使用 JAXB 的新手,我使用 JAXB 2.1.3 的 xjc 从我的 XML 模式生成一组类。除了为我的架构中的每个元素生成一个类之外,它还创建了一个 ObjectFactory 类。
There doesn't seem to be anything stopping me from instantiating the elements directly, e.g.
似乎没有什么能阻止我直接实例化元素,例如
MyElement element = new MyElement();
whereas tutorials seem to prefer
而教程似乎更喜欢
MyElement element = new ObjectFactory().createMyElement();
If I look into ObjectFactory.java, I see:
如果我查看 ObjectFactory.java,我会看到:
public MyElement createMyElement() {
return new MyElement();
}
so what's the deal? Why should I even bother keeping the ObjectFactory class around? I assume it will also be overwritten if I were to re-compile from an altered schema.
怎么了?为什么我还要费心保留 ObjectFactory 类?我认为如果我要从更改过的模式重新编译,它也会被覆盖。
采纳答案by Chris Jester-Young
Backward compatibility isn't the only reason. :-P
向后兼容性并不是唯一的原因。:-P
With more complicated schemas, such as ones that have complicated constraints on the values that an element's contents can take on, sometimes you need to create actual JAXBElement
objects. They are not usually trivial to create by hand, so the create*
methods do the hard work for you. Example (from the XHTML 1.1 schema):
对于更复杂的模式,例如对元素内容可以采用的值具有复杂约束的模式,有时您需要创建实际JAXBElement
对象。手工创建它们通常不是微不足道的,因此这些create*
方法可以为您完成艰苦的工作。示例(来自 XHTML 1.1 模式):
@XmlElementDecl(namespace = "http://www.w3.org/1999/xhtml", name = "style", scope = XhtmlHeadType.class)
public JAXBElement<XhtmlStyleType> createXhtmlHeadTypeStyle(XhtmlStyleType value) {
return new JAXBElement<XhtmlStyleType>(_XhtmlHeadTypeStyle_QNAME, XhtmlStyleType.class, XhtmlHeadType.class, value);
}
This is how you get a <style>
tag into a <head>
tag:
这是将<style>
标签放入<head>
标签的方法:
ObjectFactory factory = new ObjectFactory();
XhtmlHtmlType html = factory.createXhtmlHtmlType();
XhtmlHeadType head = factory.createXhtmlHeadType();
html.setHead(head);
XhtmlStyleType style = factory.createXhtmlStyleType();
head.getContent().add(factory.createXhtmlHeadTypeStyle(style));
The first three uses of the ObjectFactory
could be considered superfluous (though useful for consistency), but the fourth one makes JAXB much, much easier to use. Imaging having to write a new JAXBElement
out by hand each time!
的前三种用法ObjectFactory
可能被认为是多余的(虽然对一致性很有用),但第四种用法使 JAXB 更容易使用。成像必须new JAXBElement
每次都用手写出来!
回答by Bert F
Backwards compatibility, I guess ...
向后兼容性,我猜...
http://weblogs.java.net/blog/kohsuke/archive/2005/08/a_story_of_migr.html:
http://weblogs.java.net/blog/kohsuke/archive/2005/08/a_story_of_migr.html:
...No more ObjectFactory.createXYZ. The problem with those factory methods was that they throw a checked JAXBException. Now you can simply do new XYZ(), no more try/catch blocks. (I know, I know, ... this is one of those "what were we thinking!?" things)...
...没有更多的 ObjectFactory.createXYZ。这些工厂方法的问题在于它们抛出一个检查过的 JAXBException。现在您可以简单地执行 new XYZ(),不再使用 try/catch 块。(我知道,我知道,......这是“我们在想什么!?”事情之一)......
回答by skaffman
As @Chris pointed out, sometimes JAXB cannot work with POJOs, because the schema cannot be mapped exactly on to Java. In these cases, JAXBElement
wrapper objects are necessary to provide the additional type information.
正如@Chris 指出的那样,有时 JAXB 无法与 POJO 一起使用,因为模式无法准确映射到 Java。在这些情况下,需要JAXBElement
包装器对象来提供额外的类型信息。
There are two concrete examples that I've come across where this is common.
我遇到过两个具体的例子,这很常见。
If you want to marshal an object of a class that does not have the
@XmlRootElement
annotation. By default XJC only generates@XmlRootElement
for some elements, and not for others. The exact logic for this is a bit complicated, but you can force XJC to generate more@XmlRootElement
classes using the "simple binding mode"When your schema uses substituion groups. This is pretty advanced schema usage, but XJC translates substitution groups into Java by making heavy use of
JAXBElement
wrappers.
如果要封送没有
@XmlRootElement
注释的类的对象。默认情况下,XJC 只@XmlRootElement
为某些元素生成,而不为其他元素生成。这样做的确切逻辑有点复杂,但您可以@XmlRootElement
使用“简单绑定模式”强制 XJC 生成更多类当您的架构使用替换组时。这是非常高级的模式用法,但 XJC 通过大量使用
JAXBElement
包装器将替换组转换为 Java 。
So in an XJC-generated object model which makes heavy use of JAXBElement
(for whatever reason), you need a way of constructing those JAXBElement
instances. The generated ObjectFactory
is by far the easiest way to do it. You canconstruct them yourself, but it's clunky and error-prone to do so.
因此,在大量使用JAXBElement
(无论出于何种原因)的 XJC 生成的对象模型中,您需要一种构建这些JAXBElement
实例的方法。生成ObjectFactory
是迄今为止最简单的方法。您可以自己构建它们,但这样做很笨拙且容易出错。