我想编组/解组继承另一个类的类的对象 .
我从类 Thing
开始:
import java.util.List;
public class Thing {
private List<String> strings;
public List<String> getStrings() {
return strings;
}
public void setStrings(List<String> strings) {
this.strings = strings;
}
}
我扩展了这个类并使用JAXB注释对其进行注释 .
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement
public class JaxbThing extends Thing {
// @XmlElementWrapper(name = "list")
@XmlElementWrapper(name = "strings")
@XmlElement(name = "string")
public List<String> getStrings() {
return super.getStrings();
}
public void setStrings(List<String> string) {
super.setStrings(string);
}
}
然后我运行以下编组/解组程序:
import java.io.File;
import java.util.Arrays;
import javax.xml.bind.*;
public class Main {
public static void main(String[] args) {
JaxbThing t = new JaxbThing();
t.setStrings(Arrays.asList("a", "b", "c"));
try {
File f = new File("jaxb-file.xml");
JAXBContext context = JAXBContext.newInstance(JaxbThing.class);
Marshaller m = context.createMarshaller();
m.marshal(t, f);
Unmarshaller um = context.createUnmarshaller();
JaxbThing t2 = (JaxbThing) um.unmarshal(f);
System.out.println(t2.getStrings()); // I expect to see [a, b, c]
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
XML文件的内容是:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxbThing>
<strings>
<string>a</string>
<string>b</string>
<string>c</string>
</strings>
</jaxbThing>
一切似乎都是正确的 . 但解密的结果让我感到惊讶,因为控制台显示:
[
]
当我期望看到 [a, b, c]
如果我以这种方式注释 strings
属性:
@XmlElementWrapper(name = "list")
// @XmlElementWrapper(name = "strings")
@XmlElement(name = "string")
public List<String> getStrings() {
return super.getStrings();
}
然后控制台显示预期的 [a, b, c]
.
我猜JAXB unmarshaler使用类 Thing
而不是 JaxbThing
来解组XML文件内容 . 事实上,如果我使用 @XmlTransient
注释类 Thing
,我会得到预期的结果 .
但是我不明白JAXB的这种行为 .
有人可以解释一下吗,拜托?先感谢您 .
2 回答
问题是您要从父类重写属性 . JAXB认为
JAXBThing
有“一个名为
strings
(继承自String
)的属性映射到元素strings
.一个名为
strings
的属性(在JAXBThing
上定义,映射到元素strings
下的元素string
.如果在
JAXBThing
上的setStrings
方法中设置断点,您将看到它首先使用正确的数据进行调用,然后第二次使用不正确的数据来覆盖初始集(因为它认为它们是共享的不同属性一个二传手 .您始终可以通过使用
@XmlTransient
注释来删除Thing
类 .For More Information
非常感谢您的回答 . 我做了你建议我的事 . 你是对的,
setStrings
方法被调用两次 . 但是,至少在我的实验中,它永远不会被调用正确的值 .Bellow我提供修改后的示例代码 . 我添加了几行来跟踪执行情况 . 我还激活了marshaller格式化输出,以便更好地了解解组过程中会发生什么 .
基类
Thing
扩展类
JaxbThing
测试程序:
结果如下(我已对行编号):
在解组期间,构建了一个新的
JaxbThing
,它首先使用0长度的字符串列表(第7行)调用JaxbThing.setStrings
. 因此,Thing.setStrings
被调用(第8行) . 对象的字符串字段(this.strings
)的先前值为null . 然后,再次调用JaxbThing.setStrings
(第10行),但现在有一个字符串列表,其中包含一个带有'\n'字符的字符串加上4个空格(我猜这对应于XML文件的缩进) . 两个评论:永远不会使用正确的值调用
JaxbThing.setStrings
(除非我没有看到它) .第二次调用
JaxbThing.setStrings
(第10行)导致第二次调用Thing.setStrings
(第11行) . 但是现在this.strings
的前一个值不是在第8行的前一次调用Thing.setStrings
中设置的0长度字符串列表 . 它已经是'\n'字符加上4个作为参数传递的空格 .解释这种行为的任何线索?