正如标题所说,我有两个实现相同接口的不同对象,我想将它们添加到同一个集合中。
我的 XML 看起来像:
<root>
<item-list>
<item>
<type1>
<id>1</id>
</type1>
</item>
<item>
<type2>
<id>2</id>
<other>1</other>
</type2>
</item>
</item-list>
</root>
下面的标签item
可以是type1
或type2
随时。它们具有相似的值,但如您所见,它们type2
具有另一个字段。
我的界面是:
public interface Item {
public String getID();
}
我的三门课:
public class MyObj {
private ArrayList<Item> items = new ArrayList<Item>();
public List<Item> getItems() {
return items;
}
}
public class Type1 implements Item{
private String id;
@Override
public String getID() {
return id;
}
}
public class Type2 implements Item {
private String id;
private String other;
@Override
public String getID() {
return id;
}
public String getOther() {
return other;
}
}
我的绑定看起来像这样:
<binding direction="input" >
<mapping name="item-list" class="jibx.woe.MyObj" >
<collection field="items" >
<structure name="item" choice="true" ordered="false">
<structure name="type1" map-as="type1"/>
<structure name="type2" map-as="type2"/>
</structure>
</collection>
</mapping>
<mapping class="jibx.woe.Type1" abstract="true" type-name="type1">
<value name="id" field="id"/>
</mapping>
<mapping class="jibx.woe.Type2" abstract="true" type-name="type2">
<value name="id" field="id"/>
<value name="other" field="other"/>
</mapping>
当我运行它时,我得到了这个错误:
*** Error during code generation for file 'C:\Projects\IdeaProjects\jibx-woe\src \main\config\woe-binding.xml' -
this may be due to an error in your binding or classpath, or to an error in the JiBX code ***
Internal error: Expected jibx.woe.Type1 on stack, found java.lang.Object full stack:
0: java.lang.Object
1: java.lang.Object
2: org.jibx.runtime.impl.UnmarshallingContext
所以我想我向集合添加一个项目类型,所以现在我的集合部分看起来像:
<collection field="items" item-type="jibx.woe.Item">
<structure name="item" choice="true" ordered="false" >
<structure name="type1" map-as="type1"/>
<structure name="type2" map-as="type2"/>
</structure>
</collection>
现在错误说:
Internal error: Expected jibx.woe.Type1 on stack, found jibx.woe.Item
full stack:
0: jibx.woe.Item
1: jibx.woe.Item
2: org.jibx.runtime.impl.UnmarshallingContext
所以现在我将以下方法添加到MyObj
:
public void addItem(Object type) {
items.add((Item)type);
}
并将collection
标签更改为:
<collection add-method="addItem">
并得到与我第一次尝试相同的错误:
Internal error: Expected jibx.woe.Type1 on stack, found java.lang.Object
full stack:
0: java.lang.Object
1: java.lang.Object
2: org.jibx.runtime.impl.UnmarshallingContext
现在我没有主意了。我怎样才能让它工作?
编辑
根据 Archie 在下面的建议,我将绑定更改为:
<mapping name="root" class="jibx.woe.MyObj">
<structure name="item-list" >
<collection field="items">
<structure name="item" /> >
</collection>
</structure>
</mapping>
<mapping name="type1" class="jibx.woe.Type1" >
<value name="id" field="id"/>
</mapping>
<mapping name="type2" class="jibx.woe.Type2" >
<value name="id" field="id"/>
<value name="other" field="other"/>
</mapping>
</binding>
现在绑定工作没有堆栈错误(万岁!)但是现在当我从我的列表中获得一个项目时:
List<Item> items = woe.getItems();
Type1 item = (Type1) items.get(0);
我得到:
java.lang.ClassCastException: java.lang.Object cannot be cast to jibx.woe.Type1
在我上面的第二行。如果我打印对象: System.out.println(items.get(0));
它说:java.lang.Object@1be2d65
所以它是一个普通的对象,根本不是 Element 或 Type1(或 Type2)!
我确实尝试了 Archie 提出的“扩展”方法,但它并没有改变任何东西——我得到了相同的结果。