Search code examples
javaxstream

Variable initialization past Xstream


Consider the following declaration as part of SomeClass

private Set<String> blah    = new HashSet<String>();

Made in a class, which is later

XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.setMode(XStream.NO_REFERENCES);

StringBuilder json = new StringBuilder(xstream.toXML(SomeClass));

rd = (SomeClass) xstream.fromXML(json.toString());

When i @Test

assertTrue(rd.getBlah().size() == 0);

I get an NPE on rd.getBlah()

When I, instead of initializing up front, place initialization to a constructor of SomeClass

public SomeClass() {
  blah = new HashSet<String>();
}

Same problem - NPE on rd.getBlah()

When i modify the getter to check for null first, it works, but ..

public Set<String> getBlah() {
   if (blah == null)
      return new HashSet<Sgring>();
   return blah;
}

I am puzzled ... Why does XStream not initialize variables and whether lazy instantiation is necessary?


Solution

  • XStream uses the same mechanism as the JDK serialization. When using the enhanced mode with the optimized reflection API, it does not invoke the default constructor. The solution is to implement the readResolve method as below:

    public class SomeClass{
        private Set<String> blah;
    
        public SomeClass(){
            // do stuff
        }
    
        public Set<String> getBlah(){
            return blah;
        }
    
        private Object readResolve() {
            if(blah == null){
                blah = new HashSet<String>();
            }
            return this;
        }
    }
    

    Reference