使用Java Generics返回包装对象

时间:2018-02-28 16:54:27

标签: java generics

我正在尝试编写一个过滤问题的通用解决方案,其中我们有几个列表将受到过滤器(或约束)列表的约束。

支持这一点,我有以下通用类:

public class Constrained<T> {
    private T object;

    List<TraitFilter> filters;

    public T getObject() {
        return object;
    }
}

这将允许我有一个由约束列表包装的任何类的对象。

现在我正在尝试编写可以运行过滤器的服务。我希望能够像这样在服务中编写函数:

List<T> filtered(Constrained<T>, traits);

但是Java并不喜欢这样。它说T没有定义。我交换了以下内容:

List<? extends Object> filtered(List<Constrained<?>> possible, Traits traits);

这样的Java,在定义函数的接口和实现中,直到我编写实际尝试使用该函数的测试。

final List<Constrained<DecisionTemplate>> dtList =
   Arrays.asList(ConstrainedDecisionTemplateFixtures.LUO_ONLY_POLICIES(),
                 ConstrainedDecisionTemplateFixtures.LUOA_AGREEMENT());

List<DecisionTemplate> actual = instance.filtered(dtList, expectedTraits);

我的IDE报告以下错误消息:

 Wrong 1st argument type. Found
 'java.util.List<Constrained<DecisionTemplate>>', required:
 'java.util.List<Constrained<? extends java.lang.Object>>

我需要更改什么才能使用返回类T的展开对象的泛型函数?

1 个答案:

答案 0 :(得分:0)

为了能够宣布:

List<T> filtered(List<Constrained<T>> traits);

(请注意,我假设您所需的参数实际上是List Constrained,而不是单个参数... ...

您需要声明方法为通用的接口,并使用T进行参数化。

您需要将实现范围缩小到特定的参数化类型,即实现中的DecisionTemplate

您还可以使用以下语法声明泛型方法:

<T extends DecisionTemplate>List<T> filtered(List<Constrained<T>> traits);

...如果您不想拥有通用界面。

示例

// with a generic method...
interface Foo {
    <T extends DecisionTemplate>List<T> filtered(List<Constrained<T>> traits);
}
class Blah implements Foo {
    @Override
    public <T extends DecisionTemplate> List<T> filtered(
        List<Constrained<T>> traits) {
        // TODO populate
        return null;
    }
}

// with a generic class/interface
interface FooGeneric<T> {
    List<T> filtered(List<Constrained<T>> traits);
}
class BlahGeneric implements FooGeneric<DecisionTemplate> {
    @Override
    public List<DecisionTemplate> filtered(
        List<Constrained<DecisionTemplate>> traits) {
        // TODO populate
        return null;
    }
}

<强>客户

// invoking generic method

// TODO populate
List<Constrained<DecisionTemplate>> list = new ArrayList<>(); 
List<DecisionTemplate> filtered = new Blah().filtered(list);

// invoking generic class/interface's method

// TODO populate
List<Constrained<DecisionTemplate>> anotherList = new ArrayList<>();
List<DecisionTemplate> anotherFiltered = new BlahGeneric().filtered(anotherList);