2016-12-31 89 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,我將在對象中使用與上一次運行不同的值。不確定這一點。 –