Java JAXB框架是Java平台中用于将XML数据和Java对象进行相互转换的标准技术,XmlAccessType注解用于定义JAXB在绑定XML元素和Java对象时的访问模式,其中FIELD和PROPERTY是最常用的两种模式,二者的核心差异体现在映射范围、对成员方法的依赖等多个层面。

XmlAccessType基础概念
XmlAccessType是javax.xml.bind.annotation包下的枚举类型,用于指定JAXB实现在绑定Java类与XML时的成员访问策略,常见的取值包括FIELD、PROPERTY、PUBLIC_MEMBER、NONE四种,本文重点对比FIELD和PROPERTY两种模式的差异。
当我们在Java类上添加@XmlAccessorType注解时,就可以指定对应的访问模式,例如:
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
// 指定访问模式为FIELD
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
// 类成员定义
}
FIELD访问模式的特点
FIELD模式的核心逻辑是JAXB直接访问Java类的实例字段(成员变量),无论字段的访问权限是public、private还是protected,只要没有添加@XmlTransient注解,都会被映射到XML中。
映射规则
- 映射范围:所有未被
@XmlTransient标记的实例字段,包括private、protected、public修饰的字段 - 方法无关性:getter和setter方法的存在与否、访问权限不会影响映射结果,JAXB不会主动调用这些方法
- 注解位置:和字段相关的JAXB注解(如
@XmlElement、@XmlAttribute)需要直接标注在字段上
代码示例
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class UserFieldMode {
// private字段会被直接映射
@XmlElement(name = "user_name")
private String name;
// 没有getter setter的字段也会被映射
private int age;
// 公共字段也会被映射
public String email;
// 存在getter setter但不影响映射逻辑
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
上述类转换为XML后的结果如下:
<user>
<user_name>张三</user_name>
<age>20</age>
<email>test@ipipp.com</email>
</user>
PROPERTY访问模式的特点
PROPERTY模式的核心逻辑是JAXB通过Java类的getter和setter方法来访问成员,只有符合JavaBean规范的属性(即有对应的getter和setter方法)才会被映射到XML中,实例字段本身不会被直接处理。
映射规则
- 映射范围:所有符合JavaBean规范的属性,即存在public的getter和setter方法的成员,和字段本身的访问权限无关
- 方法依赖性:如果只有字段没有对应的getter/setter方法,该成员不会被映射到XML中
- 注解位置:和属性相关的JAXB注解需要标注在getter方法上,标注在字段上不会生效
代码示例
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class UserPropertyMode {
private String name;
private int age;
// 没有getter setter的字段,不会被映射
private String address;
// getter方法上标注注解才会生效
@XmlElement(name = "user_name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 没有标注注解的getter,使用默认映射名
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 没有getter方法,address不会被映射
public void setAddress(String address) {
this.address = address;
}
}
上述类转换为XML后的结果如下:
<user>
<user_name>李四</user_name>
<age>25</age>
</user>
两种模式的核心差异对比
| 对比维度 | FIELD模式 | PROPERTY模式 |
|---|---|---|
| 映射对象 | 类的实例字段 | 符合JavaBean规范的属性(getter/setter) |
| getter/setter要求 | 不要求存在,存在也不影响映射 | 必须存在public的getter和setter,否则不映射 |
| 注解标注位置 | 字段上 | getter方法上 |
| private字段处理 | 会被映射 | 不会被映射(除非有对应的getter/setter) |
| 无方法字段处理 | 会被映射 | 不会被映射 |
使用场景建议
如果Java类的字段大多是private修饰,且没有对应的getter/setter方法,或者希望直接控制字段和XML的映射关系,优先选择FIELD模式;如果项目遵循严格的JavaBean规范,所有成员都有对应的getter/setter方法,且希望在方法层面控制映射逻辑,优先选择PROPERTY模式。
需要注意的是,如果类中同时混合使用了两种模式的注解,且没有显式指定@XmlAccessorType,默认会使用PUBLIC_MEMBER模式,即映射所有public的字段和public的getter/setter对应的属性,此时容易出现映射不符合预期的问题,建议显式指定访问模式。
JAXBXmlAccessTypeField访问模式Property访问模式Java修改时间:2026-07-14 17:36:14