简体   繁体   English

通用List类型的getter和setter上的接口

[英]Interface on getter and setter of generic List type

We're trying to extract an interface in a library containing versioned sets of beans (used in an XML webservice). 我们正在尝试在包含版本集的bean(在XML Webservice中使用)的库中提取接口。 The models themselves use only other models from the same version. 这些模型本身仅使用同一版本的其他模型。

There are mostly only getters and setters, and as the versions are quite similar, the process works well most of the time. 多数情况下只有getter和setter,而且由于版本非常相似,因此该过程在大多数情况下都运行良好。 There is a bit of a hiccup as it comes to List types though. 不过,在列表类型方面有点麻烦。

Let's take an example: 让我们举个例子:

public class Attribute implements IAttribute

This is used elsewhere: 这在其他地方使用:

public class Product implements IProduct {
    List<Attribute> products = new ArrayList<Attribute>();
}

The interface IProduct has this getter and setter: 接口IProduct具有此getter和setter:

public interface IProduct {
    public abstract List<? extends IAttribute> getAttributes();
    public abstract void setAttributes(List<? extends IAttribute> attributes);
}

The class Product then has this getter and setter: 然后,类Product具有此getter和setter:

public List<Attribute> getAttributes() {
    return attributes;
}

public void setAttributes(List<? extends IAttribute> attributes) {
    this.attributes = attributes;
}

There is, of course, an error on the setter: the field attributes in Product is a List of Attribute, and is narrower than a List of wildcard extending IAttribute. 设置器上当然有一个错误:Product中的字段属性是一个属性列表,并且比扩展IAttribute的通配符列表要窄。 It feels like a catch 22 though. 虽然感觉像一个陷阱22。 If we widen the declaration of the field itself, we lose the benefit of specificity. 如果扩大字段本身的声明,我们将失去特异性的好处。 There are then also issues implementing an add method (addAttribute(Attribute attribute)). 然后,还有实现add方法(addAttribute(属性属性))的问题。

One ugly solution would be to iterate over the List of wildcard extending IAttribute, do type checking and add only if the actual type of the objects inside are Attribute of the correct version. 一种丑陋的解决方案是遍历扩展IAttribute的通配符列表,进行类型检查并仅在内部对象的实际类型是正确版本的Attribute时添加。

public void setAttributes(List<? extends IAttribute> attributes) {
    this.attributes = new ArrayList<Attribute>();
    for (Attribute attribute : attributes) {
        if (!(attribute instanceof Attribute)) {
            throw new IllegalArgumentException();
        } else {
            this.attributes.add((Attribute)attribute);
        }
    }
}

Is there a better, more robust, more elegant way to do this? 有没有更好,更强大,更优雅的方法来做到这一点?

I have the feeling that IProduct should be a generic interface: 我觉得IProduct应该是通用接口:

public interface IProduct<T extends IAttribute> {
    public abstract List<T> getAttributes();
    public abstract void setAttributes(List<T> attributes);
}

and that the Product should be defined as 并且该产品应定义为

public class Product implements IProduct<Attribute> {
    private List<Attribute> attributes;

    @Override
    public List<Attribute> getAttributes() {
        return attributes;
    }

    @Override
    public void setAttributes(List<Attribute> attributes) {
        this.attributes = attributes;
    }
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM