XMLEncoder writeObject skips properties initialized in constructor

588 Views Asked by At

How does XMLEncoder know that a property was set in the object's constructor, and thus avoid outputting it ?

Here is a simple example (run on Java 1.8) which demonstrates this: First define a simple object with getters and setters and a default constructor:

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;
 }      
}

Now the main, which instantiates the object, uses a setter on one of the properties, and invokes XMLEncoder on the final object. To be sure I also print the object's properties before invoking the encoder:

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();
  }
 }

Running the program, I get the expected output: m=1,n=7 However, when I look at the file generated, I get:

<?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>

Here we see that the only one property is output by XMLEncoder, whereas the previous printout of the object shows that both properties have their values set. It is as though XMLEncoder has a crystal ball and knows what happened in the past!

1

There are 1 best solutions below

4
On

It actually looks the opposite, as if it has amnesia, it could have output both n and m but it did only print one property, the one that was affected by your setter.

But Official doc says

Structurally compact: The XMLEncoder class uses a redundancy elimination algorithm internally so that the default values of a Bean's properties are not written to the stream.

So it explains its selective nature