我試圖用MOXY/JAXB 2.5.0實現四人幫的原型模式版本。我希望能夠指定一個項目列表,其中一些是「基於」其他項目,即從其他實例複製數據。對於可重用性,我想創建一個接口,任何能夠實現原型的對象都應該實現這個接口,它將提供註釋以支持該模式所需的屬性。MOXy/JAXB「原型模式」 - 接口繼承
@XmlRootElement(name="IPrototype")
public interface IPrototype
{
/**
* Acts as a "copy constructor"
*/
@XmlAttribute(name="prototype")
@XmlIDREF
public void setPrototype(IPrototype prototype);
@XmlAttribute(name="id")
@XmlID
public void setId(String id);
public String getId();
}
的實施對象將理想是這個樣子,甚至沒有與從該接口實現的方法註釋打擾:
@XmlRootElement(name="Item")
public class Item implements IPrototype
{
private String m_id = null;
private String m_data = null;
public Item()
{
}
/**
* Never called
*/
@Override
public void setPrototype(IPrototype prototype)
{
m_data = ((Item)prototype).getData();
}
@Override
public void setId(String id)
{
m_id = id;
}
@Override
public String getId()
{
return m_id;
}
@XmlAttribute(name="data")
public void setData(String data)
{
m_data = data;
}
public String getData()
{
return m_data;
}
}
和XML看起來像:
<Wrapper>
<Item id="Item1" data="stuff and things" />
<Item id="Item2" prototype="Item1" />
</Wrapper>
其中Wrapper定義爲:
@XmlRootElement(name="Wrapper")
public class Wrapper
{
@XmlElementRef
private ArrayList<Item> m_items = null;
}
如果按照我想要的方式工作,我會得到一個包含兩個元素的列表,這兩個元素都包含相同數據的Item類型。然而,MOXy似乎沒有「看到」接口上的註釋,並且我得到了一個沒有設置其XmlID的兩個Items的列表,並且setPrototype()從不被調用。唯一的解決方案似乎是註解Item類中的setPrototype()和setId()方法,但是這似乎需要將setPrototype()的參數類型從IPrototype更改爲Item,因此MOXy將在正確的類中查找XmlID。不幸的是,這打破了繼承的接口。
如果我改爲將列表類型更改爲IPrototype,希望允許MOXy查看其註釋,我會得到相同的行爲 - null ID,setPrototype()永遠不會調用。這實際上並不是我想要的,我希望能夠限制哪些亞型可能包含在特定列表中。
不知道我對接口註釋應該如何工作有正確的期望,也許這是我的錯誤的來源。
有關如何使這項工作的任何想法?在此先感謝,
史蒂夫
更新:如果我註釋Item類,在不改變setPrototype的方法簽名(我想我可以住在一起),我得到的列表,包括兩個項目,以正確設置XmlID的,但setPrototype()仍未調用。看起來像MOXy正在尋找具有相同XmlID而不是Item實例的IPrototype實例(不可能)。
更新2:而且,如果我將IPrototype轉換爲抽象類,那麼一切都很完美。但是,鑑於Java的單一繼承模型,這對於旨在補充多重繼承層次結構的框架對象來說太過於限制。所以仍然卡住。
但是,如果我試圖用限制類型參數的申報方法不起作用:公共 void setPrototype(T prototype)。我收到一個異常抱怨說IPrototype沒有用@XmlID註解的屬性。如果我註釋這些方法,那麼setPrototype()不會被調用。現在無界限。 –