【问题标题】:Generic inside a generic泛型中的泛型
【发布时间】:2012-12-04 16:05:55
【问题描述】:

首先,我想向您展示我想要实现的目标。 我想从如下所示的类中生成一个 XML 文件:

<config>
    <criteria name="criteriaName" defaultValue="0">
        <item value="1">
            <criteria name="criteriaName2" defaultValue="">
                <item value="foo">
                </item>
                <item value="bar">
                </item>
            </criteria>
        </item>
        <item value="2">
        </item>
    </criteria>
    <criteria name="criteriaName3" defaultValue="">
        <item value="foo">
        </item>
    </criteria>
</config>

总结:

  • Criteria 有一个名称和一个默认值(可以是 String、int 或 double) 和 x 项作为子项。
  • Item 有一个值,该值必须与父条件 defaultValue 的类型相同。
  • 一个项目也可以包含另一个条件。条件中defaultValue的类型独立于父(item)类型

例如:

criteria (type int)
   item (type int)
      criteria(type String)
         item(type String)

我还需要类形式的这个模型,因为我想稍后用它做一些验证。

现在我在一个特定的点上挣扎,让我先向你展示我的课程:

配置:

@XmlAccessorType(value=XmlAccessType.FIELD)
@XmlRootElement(name="config")
public class Config {

    @XmlElement(name = "criteria")
    private List<Criteria> criteriaList = new ArrayList<Criteria>();

    /*getters and setters*/
}

标准:

@XmlAccessorType(value=XmlAccessType.FIELD)
@XmlRootElement(name="criteria")
public class Criteria<T> {

    @XmlAttribute
    private T key;

    @XmlAttribute
    private String display;

    @XmlAttribute
    private T defaultValue;

    private List<Item<T>> items = new ArrayList<Item<T>>();

    public T getKey() {
        return key;
    }
    /*getters and setters*/
}

项目:

@XmlAccessorType(value=XmlAccessType.FIELD)
@XmlRootElement(name="item")
public class Item<T>{

    @XmlAttribute
    protected T key;

    @XmlAttribute
    protected String display;

    @XmlElement
    protected List<Criteria<T>> criteria = new ArrayList<Criteria<T>>();

    /*getters and setters*/
}

这样我可以创建一个特定类型的条件,其中包含相同类型的项目。

现在我想在项目下插入一个标准,它的类型与项目不同,但这是不可能的:

    Config config = new Config();
    Criteria<Integer> criteria = new Criteria<Integer>();
    Item<Integer> item = new Item<Integer>();

    Criteria<String> subCriteria = new Criteria<String>();
    //this obviously doesn't work
    item.getCriteria().add(subCriteria); //<--

    criteria.getItems().add(item);
    config.addCriteria(criteria);

我也尝试过类似这样的声明(在项目中):

@XmlElement
protected <U> List<Criteria<U>> criteria;

但这仅适用于方法,不适用于属性。

谁能帮忙?

【问题讨论】:

    标签: java xml generics jaxb


    【解决方案1】:

    我认为您已经非常接近解决问题了。主要问题是

    protected Criteria<T> criteria = new ArrayList<Criteria<T>>();
    

    不正确。根据您的要求,条件不必与父项具有相同的类型。 我看到的一种可能性是

     protected Criteria<?> criteria = new ArrayList<Criteria<?>>();
    

    现在唯一的问题是,我认为您将收到警告/当您尝试在列表中插入或获取元素时,您将不得不强制转换。

    【讨论】:

      【解决方案2】:

      这个怎么样。

      类项目:

      public class Item<T,U>{
      
          protected T key;
      
          protected String display;
      
          protected Criteria<U> criteria = new Criteria<U>();
      
          /*getters and setters*/
      }
      

      类标准:

      public class Criteria<T> {
      
          private T key;
      
          private String display;
      
          private T defaultValue;
      
          private List<Item<T,?>> items = new ArrayList<Item<T,?>>();
      
          public T getKey() {
              return key;
          }
          /*getters and setters*/
      }
      

      基本上,我们是说您有一个具有另一种类型 U 的项目作为内部标准。这样你必须提前指定一个Item对象的Criteria类型,但是你可以将不同Criteria类型的Item混合到同一个Criteria中,如下sn-p所示:

      Criteria<String> c1 = new Criteria<String>();
      c1.items.add(new Item<String,Float>());
      c1.items.add(new Item<String,Integer>());
      

      【讨论】:

      • 这是一个非常好的建议。但是,现在将 java 对象编组为 XML 似乎存在问题。我认为 JAXB 无法处理泛型。注意:如果没有泛型(字符串),它会按预期工作(在编组方面)。我现在的解决方案是:创建泛型,然后对它们进行验证或将它们映射到另一个非泛型的数据结构并编组它们。
      • 这样你能把Criteria的泛型与Item的泛型解耦吗?
      • 我上面提到的是一个往返,我必须去得到我想要的 XML 输出。我应该提到,我只需要在运行时使用泛型类型(用于验证)。在我的具体情况下,我永远不必将 xml 解组回我的模式。说明:XML 是 Web 服务调用的配置。我在运行时获得(通用)配置,并使用从调用者那里获得的字段验证这些配置。 XML 部分仅用于为调用者提供“允许”输入字段的形式
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多