2015-11-16 107 views
0

我正在使用JAXB將對象保存到xml文件。unmarshal同步映射

@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得到這個工作。 但令我驚訝的是,這些元帥和unmarshals罰款。測試顯示它正確使用包含LinkedHashMap$Entry對象的java.util.Collections$SynchronizedMap

所以,如果我理解正確。 JAXB的unmarshaller,只是使用構造函數實例化我的對象。由於在實例化對象後已經有一個地圖實例,因此它不會實例化地圖本身。它使用我假設的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); 
    } 
} 

回答

0

通過JAXB使用的策略是創建容器類,只有當它是必要的。對於綁定到一個列表什麼,JAXB的XJC創建

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

,因此,反編組另一個富被添加到這個列表中,基本上

parent.getFoos().add(foo); 

確實至於地圖:大概的工作版本你的班級SomeJAXBObject包含一個getMap方法,並且這將以相同的方式工作。列表和地圖的設置者不是必需的,如果有的話,它們將不會被使用。父類中的put方法也沒有預料到;如果存在的話,它將不會被使用,因爲JAXB無法知道它做了什麼。

+0

'@ XmlAccessorType'設置爲鍵入'FIELD'。但我想本質上它是一樣的:'parent.foos.add(foo)',對吧? – bvdb

+0

訪問器類型主要用於定義要進行(未)編組的項目選擇。它沒有說明實際使用什麼訪問方法,公共getter將是第一選擇。 – laune