如何在子类B中重命名父类A的JAXB属性id为somethingId?
这个问题的核心在于JAXB的访问类型(XmlAccessorType)优先级和字段/方法的处理逻辑。你之前的尝试没生效,是因为子类B用的是FIELD访问类型,JAXB会直接处理父类A的id字段(哪怕它是private,JAXB能通过反射访问),而你在方法上加的@XmlTransient对字段级别的序列化没有影响。
给你两种可行的解决方案,都不需要修改父类A(毕竟其他子类还要用原来的id字段):
方案一:切换子类B的访问类型为PROPERTY
把子类B的XmlAccessorType改成PROPERTY,这样JAXB会优先处理方法而非字段。然后重写父类的getId()和setId()并标记@XmlTransient,同时提供somethingId的getter/setter并标注@XmlElement:
@XmlType @XmlAccessorType(XmlAccessType.PROPERTY) // 切换为方法级访问 class B extends A { private int x; private int y; private int z; // 重写父类的getId,标记为XmlTransient,让JAXB忽略这个属性 @Override @XmlTransient public int getId() { return super.getId(); } @Override @XmlTransient public void setId(int id) { super.setId(id); } // 自定义somethingId的属性,指定XML元素名 @XmlElement(name = "somethingId") public int getSomethingId() { return super.getId(); } public void setSomethingId(int id) { super.setId(id); } // 别忘了给x、y、z添加@XmlElement注解,因为现在访问类型是PROPERTY @XmlElement public int getX() { return x; } public void setX(int x) { this.x = x; } @XmlElement public int getY() { return y; } public void setY(int y) { this.y = y; } @XmlElement public int getZ() { return z; } public void setZ(int z) { this.z = z; } }
方案二:在子类B中重新声明id字段并标记XmlTransient
如果不想切换访问类型,还可以在子类B中重新声明id字段并标记@XmlTransient,这样JAXB会忽略这个字段(包括父类的同名字段,因为子类的字段会隐藏父类的),同时提供somethingId的getter/setter:
@XmlType @XmlAccessorType(XmlAccessType.FIELD) class B extends A { @XmlTransient // 标记这个字段为忽略,JAXB不会序列化它 private int id; private int x; private int y; private int z; // 自定义somethingId的XML元素 @XmlElement(name = "somethingId") public int getSomethingId() { return super.getId(); } public void setSomethingId(int id) { super.setId(id); } // 这里x、y、z不需要额外注解,因为访问类型是FIELD }
注意:这两种方案都需要父类A提供getId()和setId()的公共/保护方法,否则子类无法访问父类的id字段。如果父类A没有这些方法,你需要先给A添加getter/setter(其他子类不受影响)。
内容的提问来源于stack exchange,提问作者Rade_303
相关产品推荐
相关产品推荐

