我正在尝试为过滤问题编写一个通用解决方案,其中我们有几个列表,这些列表将受到过滤器列表(或约束(的约束。
为了支持这一点,我有以下泛型类:
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 的解包对象的泛型函数?
能够声明:
List<T> filtered(List<Constrained<T>> traits);
(请注意,我假设您想要的参数实际上是Constrained
的List
,而不是单个(...
您需要将方法声明为泛型并使用 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);