放在 getter、setter 和成员上的 JAXB 注释有啥区别?

Posted

技术标签:

【中文标题】放在 getter、setter 和成员上的 JAXB 注释有啥区别?【英文标题】:What's the difference between JAXB annotations put on getter versus setters versus members?放在 getter、setter 和成员上的 JAXB 注释有什么区别? 【发布时间】:2014-04-07 09:53:46 【问题描述】:

标题说明了一切。

我想知道将 JAXB 注释(如@XmlElement)放在字段/getter/setter 上的主要区别是什么。在我看来(在简单的情况下)这并不重要。

例如让我们拿这个

class A  
    private String a;

    public String getA()  return a; 

    public void setA(String a)  this.a = a; 

现在在我看来,将@XmlElement 放在成员字段或getter / setter 上并不重要。它只是编组好。当我需要有所作为时,是否有任何用例?

当我去解组这个(xml 回到 A)时,JAXB 具体做什么?

我正在使用 JAXB MOXy 实现

谢谢

【问题讨论】:

【参考方案1】:

我发现在 setter 方法和 getter 方法上标记 JAXB 注释没有区别。我测试了编组和解组,它们都运行良好。但是你应该只注释其中一个; getter 方法或 setter 方法;你不能同时注释两者,否则你会得到一个运行时异常,如下所示。

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:445)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:147)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:462)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)

【讨论】:

【参考方案2】:

默认情况下,JAXB 实现会将属性(get/set 对)、公共字段(实例变量)和带注释的非公共字段视为映射。如果你只是注释一个字段,你会得到一个重复的映射属性异常。

如果你想注释字段,你应该在类上指定@XmlAccessorType(XmlAccessType.FIELD)

更多信息

http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html

【讨论】:

我得到了你提到的这个异常,尽管使用了 FIELD 访问器:“类有两个同名的属性“maxHttpConnectionsPerHost”,这个问题与以下位置有关 getMaxHttpConnectionsPerHost() 和 maxHttpConnectionsPerHost 我不想怀疑你的话,因为我知道你是 JAXB 大师。但是,我认为即使使用@XmlAccessorType(XmlAccessType.NONE),您也可以始终将注释放在字段级别。但是,相比之下,如果您使用@XmlAccessorType(XmlAccessType.FIELD),它将假定所有公共字段都需要公开——即使是没有注释的公共字段。所以更正确的说法是:“如果你不想在 getter/setter 上添加注释,那么你应该在类上指定 .... AccessType.FIELD ...。” 您说的是正确的,所有替代方案都有效,但是将注释放在成员上与 getter/setter 有什么区别?把它放在getter或setter上有什么区别?标准是什么?应该选择哪一个?为什么?

以上是关于放在 getter、setter 和成员上的 JAXB 注释有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin类与对象 ① ( 成员属性 | Kotlin 自动为成员字段生成 getter 和 setter 方法 | 手动设置成员的 getter 和 setter 方法 | 计算属性 )

Kotlin类的初始化 ① ( 成员属性 | Kotlin 自动为成员字段生成 getter 和 setter 方法 | 手动设置成员的 getter 和 setter 方法 | 计算属性 )

kotlin getter 和 setter 期望成员声明错误?

iOS getter setter

C ++:私有结构的每个单个成员的通用getter/setter

Setter 和 getter 的必要性