3

次の宣言を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);

私はNPEオンになりますrd.getBlah()

前もって初期化する代わりに、初期化をコンストラクターに配置すると、SomeClass

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

同じ問題 -NPEオンrd.getBlah()

最初に null をチェックするようにゲッターを変更すると機能しますが、..

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

私は困惑しています...XStream変数を初期化しないのはなぜですか?また、遅延インスタンス化が必要なのですか?

4

1 に答える 1

5

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

参照

于 2012-04-04T22:34:11.110 に答える