【问题标题】:Interface on getter and setter of generic List type通用 List 类型的 getter 和 setter 接口
【发布时间】:2014-01-05 13:50:21
【问题描述】:

我们正在尝试在包含版本化的 bean 集(用于 XML Web 服务)的库中提取接口。模型本身仅使用相同版本的其他模型。

大多数情况下只有 getter 和 setter,并且由于版本非常相似,因此该过程大部分时间都运行良好。不过,对于 List 类型,有一点小问题。

举个例子:

public class Attribute implements IAttribute

这是在别处使用的:

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

接口IProduct有这个getter和setter:

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

Product 类有这个 getter 和 setter:

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

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

当然,setter 上有一个错误:Product 中的字段属性是一个属性列表,并且比扩展 IAttribute 的通配符列表更窄。不过感觉就像是第 22 条陷阱。如果我们扩大领域本身的声明,我们就会失去特异性的好处。然后还有实现添加方法(addAttribute(Attribute attribute))的问题。

一个丑陋的解决方案是遍历扩展 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);
        }
    }
}

有没有更好、更健壮、更优雅的方法来做到这一点?

【问题讨论】:

  • 如果您确定类型正确,只需强制转换并忽略警告 - this.attributes = (List&lt;Attribute&gt;) attributes。如果您不确定类型是否正确,那么您必须像所做的那样检查每个演员表。随着泛型被删除,错误的转换可能会导致代码中某处出现ClassCastException

标签: java generics interface


【解决方案1】:

我感觉IProduct应该是一个通用接口:

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

并且产品应该被定义为

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

【讨论】:

  • 感谢您的建议。不幸的是,我的代码 sn-p 远非全部情况。类中的字段更多,还有许多其他类存在类似问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
  • 1970-01-01
  • 2015-01-20
  • 1970-01-01
  • 2012-03-12
相关资源
最近更新 更多