Java 不使用默认POJO构造函数将POJO转换为XML
我正在尝试使用Java.beans.xmlcoder将POJO(普通旧Java对象)转换为XML。我的代码工作得很好,但我发现了一个有趣的问题,即当我在POJO中省略默认构造函数时出现的问题。课程如下 没有默认构造函数的POJOJava 不使用默认POJO构造函数将POJO转换为XML,java,xml,javabeans,default-constructor,Java,Xml,Javabeans,Default Constructor,我正在尝试使用Java.beans.xmlcoder将POJO(普通旧Java对象)转换为XML。我的代码工作得很好,但我发现了一个有趣的问题,即当我在POJO中省略默认构造函数时出现的问题。课程如下 没有默认构造函数的POJO public class NFLTeam implements Serializable { private String name; private String description; // public NFLTeam() { // //
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;
}
}
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);
}
<?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>
调用XMLEncoder
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;
}
}
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);
}
<?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>
省略默认构造函数的控制台输出
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>
java.lang.InstanceionException:oce.wsd.pojos.NFLTeam
持续的。。。
java.lang.Exception:XMLEncoder:丢弃语句XMLEncoder.writeObject(NFLTeam);
持续的。。。
带有默认构造函数的控制台输出
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;
}
}
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);
}
<?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>
为芝加哥队比赛
熊
我在谷歌上搜索,但找不到任何解释。为什么隐式默认构造函数对于XMLEncoder不够?来自:
如果类不包含构造函数声明,则默认
没有形式参数且没有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也不能。不幸的是,JAXB(和链接技术)需要非参数构造函数(隐式默认构造函数也可以)
根据规范,对于本机Oracle JAX库,封送和取消封送都需要它
根据人类逻辑,封送/序列化不需要它。例如,最流行的JSON库Jackson只对反序列化有这样的要求
还有第三方XML JAX兼容解析器,它们的限制性也比较小。。。但这个问题通常不是与第三方库斗争的原因
JAX允许使用非公共的非参数构造函数。我通常按如下方式创建:
/** For JAXB only. Do not call directly and do not delete! */
@Deprecated
protected NFLTeam () {
// nothing
}
我找到了我一直在寻找的答案。“XMLEncoder类是ObjectOutputStream的补充替代品,可用于生成JavaBean的文本表示。”JavaBean是这里的关键。为了使发布的示例中的NFLTeam bean被视为JavaBean,它需要前面提到的默认构造函数。“该类必须有一个公共默认构造函数(不带参数)。这允许在编辑和激活框架内轻松实例化。”我理解这一点,但我不想用默认构造函数实例化新对象。我已经构建了对象并将其传递给XMLEncoder。我猜XMLEncoder的编码方式需要一个显式的默认构造函数,我认为Java不能区分显式和隐式的n-arg构造函数。在字节码级别上,它必须看起来完全相同……我喜欢你放在里面的Javadoc。我将遵循同样的方法前进!