简体   繁体   English

如何使Jibx在集合中添加实现同一接口的两个不同对象?

[英]How do I get Jibx to add two different objects implementing the same interface in a collection?

Like the title says, I have two different objects that implement the same interface and I want to add them to the same collection. 就像标题中所说的,我有两个不同的对象实现相同的接口,我想将它们添加到同一集合中。

My XML looks like: 我的XML看起来像:

  <root>
   <item-list>
     <item>
         <type1>
            <id>1</id>
        </type1>
    </item>
    <item>
        <type2>
            <id>2</id>
            <other>1</other>
        </type2>
    </item>
  </item-list>      
</root>

The tag under item can either be type1 or type2 at any time. item下的标签可以随时为type1type2 They have similar values but, as you see, type2 has another field. 它们具有相似的值,但是,如您所见, type2还有另一个字段。

My Interface is: 我的界面是:

  public interface Item {

   public String getID();
}

My three classes: 我的三堂课:

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

My binding looks like this: 我的绑定看起来像这样:

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

And when I run it, I get the this error: 当我运行它时,出现以下错误:

*** 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

So I thought I add an item type to the collection, so now my collection section looks like: 所以我想我将一个项目类型添加到集合中,所以现在我的集合部分如下所示:

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

And the error now says: 现在错误显示:

  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

So now I add the following method to MyObj : 所以现在我将以下方法添加到MyObj

  public void addItem(Object type) {
      items.add((Item)type);
   }

And changed the collection tag to: 并将collection标签更改为:

  <collection add-method="addItem">

And get same same error as my first attempt: 并得到与我的第一次尝试相同的错误:

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

And now I'm out of ideas. 现在我没主意了。 How can I get this to work? 我该如何工作?

EDIT 编辑

Based on Archie's recommendation below, I changed my binding to: 根据以下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>

And now the binding works without stack errors (hurray!) but now when I get a item from my list a la: 现在绑定可以正常工作而不会出现堆栈错误(万岁!),但是现在当我从列表中得到一个项目时,la:

    List<Item> items = woe.getItems();
    Type1 item = (Type1) items.get(0);

I get: 我得到:

    java.lang.ClassCastException: java.lang.Object cannot be cast to jibx.woe.Type1

On my second line above. 在上面的第二行。 If I print the object: System.out.println(items.get(0)); 如果我打印对象:System.out.println(items.get(0));

It says: java.lang.Object@1be2d65 它说:java.lang.Object@1be2d65

So it's a plain object, not an Element or a Type1 (or Type2) at all! 因此,它是一个普通对象,根本不是Element或Type1(或Type2)!

I did try the "extends" method Archie proposed, but it didn't change anything -- I got the same result. 我确实尝试了Archie提出的“扩展”方法,但没有任何改变-我得到了相同的结果。

Create an abstract mapping for Item. 为Item创建一个抽象映射。 Then create two concrete mappings for Type1 and Type2, each extending the Item mapping. 然后为Type1和Type2创建两个具体的映射,每个映射都扩展了Item映射。 In your items collection, make each element an Item (get rid of the choice stuff). 在您的项目集合中,使每个元素成为一个项目(摆脱选择的东西)。

Note in JiBX the 'extends' keyword has nothing to do with Java classes, it means 'can be substituted for'. 注意,在JiBX中,“ extends”关键字与Java类无关,它表示“可以代替”。

Limitation: you will have to give Type1 and Type2 two different XML tag names (eg, "type1" and "type2") so JiBX can distinguish them when unmarshalling. 限制:您将不得不给Type1和Type2两个不同的XML标签名称(例如,“ type1”和“ type2”),以便JiBX在解组时可以区分它们。 This is the problem with what you are currently doing. 这是您当前正在做的问题。 Eg, when JiBX sees an tag, how will it know which Java class to instantiate? 例如,当JiBX看到一个标签时,它将如何知道要实例化哪个Java类?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何注册实现相同接口的类的对象 - How to register objects of classes implementing the same interface Hazelcast为带有相同类的不同类的对象的Map添加索引 - Hazelcast Adding Index for Map with Objects of different classes implementing same interface 如何使用实现相同接口的不同对象对列表进行排序? - How can I sort a list with different objects that implement the same interface? 我可以获得扩展类并实现接口的对象集合吗? - Can I get a collection of object extending a class and implementing an interface? 如何编写比较对象集合中的 2 个不同字段的比较器? - How do I write a comparator that compares 2 different fields in a collection of objects? 如何实例化同一对象的两个线程,并使对象打印不同的东西 - How do I instantiate two threads of the same object, and have the objects print different things 我如何证明 Object.hashCode() 可以为 Java 中的两个不同对象生成相同的哈希码? - How do I prove that Object.hashCode() can produce same hash code for two different objects in Java? 如何将集合中的所有对象与同一集合中的所有对象进行比较? - How do I compare all objects in a collection against all objects in the same collection? 如何在Java8中将数据从对象集合复制到不同对象的集合 - How do I copy data from a collection of objects to a collection of different objects in Java8 如何对集合中的两个不同对象进行排序? - How to sort two different objects in a collection?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM