2016-12-31 90 views
0

XMLEncoder如何知道在对象的构造函数中设置了属性,从而避免输出它?XMLEncoder writeObject跳过在构造函数中初始化的属性

下面是一个简单的例子(关于Java 1.8上运行),这说明了这一点: 首先定义一个getter和setter和默认构造方法的简单对象:

public class Simple { 
int m; 
int n; 

public int getM() { return m;} 
public void setM(int m) {this.m = m;} 
public int getN() {return n;} 
public void setN(int n) {this.n = n; } 

public String toString() { 
    return "m=" + m + ",n=" + n; 
} 

public Simple() { 
    this.m = 1; 
    this.n = 2; 
}  
} 

现在主要的,它实例化对象,在其中一个属性上使用setter,并在最终对象上调用XMLEncoder。为了确保我调用编码器之前还打印对象的属性:

public class Main { 

public static void main(String[] args) { 
    Simple simple = new Simple(); 

    simple.setN(7); 
    System.out.println(simple.toString()); 

    XMLEncoder encoder=null; 
    try{ 
     encoder=new XMLEncoder(new BufferedOutputStream(
         new FileOutputStream("simple.xml"))); 
    }catch(FileNotFoundException fileNotFound){ 
     System.out.println("ERROR: While Creating the File "); 
    } 
    encoder.writeObject(simple); 
    encoder.close(); 
    } 
} 

程序运行后,我得到预期的输出: M = 1,N = 7 然而,当我看到生成的文件,我得到:

<?xml version="1.0" encoding="UTF-8"?> 
<java version="1.8.0_112" class="java.beans.XMLDecoder"> 
<object class="simple.Simple"> 
    <void property="n"> 
    <int>7</int> 
    </void> 
</object> 
</java> 

在这里,我们看到,只有一个属性是通过输出XMLEncoder,而对象的前面打印输出显示,这两个属性有它们的值设置。就好像XMLEncoder有一个水晶球,知道过去发生了什么!

+0

看起来相反的,因为如果有失忆,它可能有两个输出n和m,但它并只打印一个属性 –

回答

0

它实际上看起来相反,就好像它有失忆症一样,它既可以输出n也可以输出m,但它只打印一个属性,受到设置者的影响。

Official doc

结构致密的:XMLEncoder类使用了冗余 消除算法内部,使得 Bean的属性的默认值不会被写入流。

所以它解释了选择性质

+0

啊,哈!这是有道理的,即当我使用XMLDecoder解码文件时,对象的实例化将初始化构造函数中的属性,并且只覆盖那些在外部设置的属性。 –

+0

是的,确切地说。不错的优化,只是不是很明显 –

+0

经过一些更多的思考,我看到这种行为的问题。如果我使用XMLEncoder存储具有某些属性的文件,则更改对象构造函数中的默认值,然后在原始文件上运行XMLDecoder,我将在对象中使用与上一次运行不同的值。不确定这一点。 –