我正在尝试编写一个过滤问题的通用解决方案,其中我们有几个列表将受到过滤器(或约束)列表的约束。
支持这一点,我有以下通用类:
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的展开对象的泛型函数?
答案 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);