2012-04-04 35 views
2

考慮以下聲明爲SomeClass變量初始化過去西河

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

製造的一類,這就是後來的

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

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

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

當我@Test

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

我得到一個部分NPErd.getBlah()

我,而不是前,地方初始化初始化高達SomeClass

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

同樣的問題構造 - NPErd.getBlah()

當我修改吸氣先檢查空,它的工作原理,但..

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

我百思不得其解......爲什麼XStream無法初始化變量以及是否需要延遲實例化?

+0

我有些困惑通過xstream.toXML(SomeClass的);它不應該是xstream.toXML(object)其中object是SomeClass類型嗎? – Max 2012-04-04 22:32:42

+0

如果有什麼我們知道的是'SomeClass'肯定是'SomeClass'類型的。:) – JAM 2012-04-05 00:16:40

+0

我的觀點是:把你在面值上面寫的東西,如果SomeClass是一個類型,那麼你的代碼在上面不編譯。 SomeClass的類型不是SomeClass的,而且也不是類型SomeClass的的SomeClass.class ... – Max 2012-04-05 01:23:34

回答

4

XStream的使用相同的機制JDK序列化。在使用增強模式和優化的反射API時,它不會調用默認的構造函數。的解決方案是實現如下所述的readResolve方法:

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

+0

謝謝。確實,這有效!兩件事情:你能提供上述的引用,請問有什麼可以找出是否我在增強模式下運行或不? – JAM 2012-04-04 22:37:52

+0

@JAM,1)我公司提供下面的代碼片段的參考和2)我不知道,但我相信它在此模式下默認運行.. – mre 2012-04-04 22:39:25

+0

爲什麼的readObject()不能在這種情況下工作嗎?我有一個類似的問題在這裏:http://stackoverflow.com/questions/15752945/xstream-wont-call-readobject其中的readObject()似乎是正確的解決方案,但只的readResolve()的作品。 – eipark 2013-04-02 13:33:02