通用内部通用

时间:2012-12-04 16:05:56

标签: java xml generics jaxb

首先,我想告诉你我想要达到的目标。 我想从类中生成一个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或 双倍)和x项作为孩子。
  • Item具有一个值,该值必须与父标准defaultValue的类型相同。
  • 项目还可以包含其他标准。条件中defaultValue的类型独立于父项(项)类型

e.g:

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

有了这个,我可以制作一个特定类型的标准,它具有相同类型的项目。

现在我想在Item下插入一个Criteria,它具有与Item不同的类型,但这不可能:

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

我也尝试了类似这个声明(在Item中):

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

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

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

我认为你非常接近解决这个问题。主要问题是

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

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

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

现在唯一的问题是,当您尝试在列表中插入或获取元素时,我认为您将收到警告/您必须进行投射。

答案 1 :(得分:0)

这是怎么回事。

班级项目:

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类型的Items混合到同一Criteria中,如此代码段所示:

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