我尝试使用java.beans.XMLEncoder将POJO(普通旧Java对象)转换为XML。我的代码工作正常,但我发现当我省略POJO中的默认构造函数时会出现一个有趣的问题。课程如下。
没有默认构造函数的POJO
public class NFLTeam implements Serializable {
private String name;
private String description;
// public NFLTeam() {
//
// }
public NFLTeam(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
调用XMLEncoder
public static void main(String args[]) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
XMLEncoder xmlEncoder = new XMLEncoder(byteArrayOutputStream);
NFLTeam team = new NFLTeam("Bears", "Play for Chicago");
xmlEncoder.writeObject(team);
xmlEncoder.close();
System.out.println(byteArrayOutputStream);
}
省略默认构造函数的控制台输出
java.lang.InstantiationException: oce.wsd.pojos.NFLTeam
Continuing ...
java.lang.Exception: XMLEncoder: discarding statement XMLEncoder.writeObject(NFLTeam);
Continuing ...
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_45" class="java.beans.XMLDecoder">
</java>
使用默认构造函数的控制台输出
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_45" class="java.beans.XMLDecoder">
<object class="oce.wsd.pojos.NFLTeam">
<void property="description">
<string>Play for Chicago</string>
</void>
<void property="name">
<string>Bears</string>
</void>
</object>
</java>
我在Google上搜索,但找不到任何解释。为什么隐式默认构造函数对XMLEncoder不够?
答案 0 :(得分:3)
不幸的是,JAXB(和链接技术)需要一个非arg构造函数(隐式默认构造函数也可以)。
根据规范和原生Oracle JAX库的情况,编组和取消编组都需要它。
根据人类逻辑,编组/序列化不需要它。例如,最受欢迎的JSON库杰克逊确实只对反序列化有这样的要求。
第三方XML JAX兼容解析器的限制性也较低......但是这个问题通常不是与第三方库挣扎的原因。
JAX允许非参数构造函数非公共。我通常按照以下方式创建它:
/** For JAXB only. Do not call directly and do not delete! */
@Deprecated
protected NFLTeam () {
// nothing
}
答案 1 :(得分:1)
来自http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9:
如果类不包含构造函数声明,则为默认值 没有形式参数且没有throws子句的构造函数 隐含地宣布。
换句话说,如果没有其他n-arg构造函数,则隐式构造函数是隐式的。亲自尝试一下:
public class Main {
public Main(int i) {
}
public static void main(String[] args) {
new Main(); // error: the constructor Main() is undefined
}
}
如果你不能,XMLEncoder也不行。
答案 2 :(得分:1)