0

オブジェクトをxmlファイルに保存するためにJAXBを使用しています。

@XmlRootElement(name="jaxbobjt")
@XmlAccessorType(XmlAccessType.FIELD)
public class SomeJAXBObject
{

  @XmlElementWrapper(name="myEntry")
  private Map<Integer, AnotherJAXBObject> map = Collections.synchronizedMap(new LinkedHashMap<Integer, AnotherJAXBObject>());
}

synchronizedMap(...)ラッパーを使用していることに注意してください。

上記の結果は、次の xml になります。

<jaxbobjt>
  <map>
    <myEntry>
      <key>key</key>
      <value>value</value>
    </myEntry>
  </map>
</jaxbobjt>

実際、これを機能させるには が必要だと思いXmlAdapterました。しかし、驚いたことに、このマーシャリングとアンマーシャリングは問題なく実行されます。テストにより、オブジェクトjava.util.Collections$SynchronizedMapを含む を正しく使用することが明らかになりました。LinkedHashMap$Entry

だから、私が正しく理解していれば。JAXB のアンマーシャラーは、コンストラクターを使用してオブジェクトをインスタンス化するだけです。オブジェクトのインスタンス化後にマップのインスタンスが既に存在するため、マップ自体はインスタンス化されません。それはputAll私が仮定する?

何が起こっているのかをより深く理解しようとしているだけです。誰かがこれについての背景情報を教えてくれるとうれしいです. 私の仮定は正しいですか?

私が正しければ、次の実装は失敗したと思います。

@XmlRootElement(name="jaxbobjt")
@XmlAccessorType(XmlAccessType.FIELD)
public class SomeJAXBObject
{
  // no instance yet.
  @XmlElementWrapper(name="myEntry")
  private Map<Integer, AnotherJAXBObject> map = null;

  public synchronized void addObject(Integer i, AnotherJAXBObject obj)
  {
    // instantiates map on-the-fly.
    if (map == null) map = Collections.synchronizedMap(new LinkedHashMap<Integer, AnotherJAXBObject>());
    map.put(i, obj);
  }
}
4

1 に答える 1

0

JAXB が使用する戦略は、必要な場合にのみコンテナ クラスを作成することです。リストにバインドされているものはすべて、JAXB の xjc が作成します

protected List<Foo> foos;
public List<Foo> getFoos(){
    if( foos == null ) foos = new ArrayList<>();
    return foos;
}

したがって、このリストに追加する別の Foo をアンマーシャリングすると、本質的に

parent.getFoos().add( foo );

マップに関しては、おそらくクラスの作業バージョンにメソッドSomeJAXBObjectが含まれておりgetMap、同じように機能します。リストとマップのセッターは不要であり、存在しても使用されません。親クラスの put メソッドも想定されていません。存在する場合、JAXB はそれが何をするかを知る方法がないため、使用されません。

于 2015-11-16T14:27:54.263 に答える