我刚刚遇到了一个不可能的泛型方法。我似乎无法编写一个方法,该方法采用JavaFX过滤列表和谓词,并简单地使用传入的谓词来过滤列表谓词。唯一的方法是在某些情况下投射哪个会导致ClassCastException
或使用Raw类型。我认为java不能代表<? super <? super String>>
。如果我遗漏了任何东西,有人能发现吗?
import javafx.collections.transformation.FilteredList;
import java.util.function.Predicate;
public class Test {
void and(FilteredList<String> l, Predicate<? super String> predicate) { //Impossible generics on 2nd parameter
l.getPredicate().and(predicate);
}
}
使用Predicate<? super Object>
不起作用,因为它不够通用:
public class Test {
<T> Predicate<? super T> and(FilteredList<T> l, Predicate<? super Object> predicate) {
return l.getPredicate().and(predicate);
}
public void exampleCall(FilteredList<Integer> integers, Predicate<Number> numberPredicate) {
return and(integers, numberPredicate); // doesn't compile
}
}
答案 0 :(得分:0)
你可以做到
void and(FilteredList<String> l, Predicate<? super Object> predicate) {
l.getPredicate().and(predicate);
}
这几乎是唯一有意义的事情。 FilteredList<String>
上的谓词的类型为Predicate<? super String>
,这是有道理的,因为在那里使用Predicate<Object>
是完全有效的。所以(如果您原谅轻微滥用语法)FilteredList<String>.getPredicate()
会返回一个谓词,该谓词可以应用于String
的某些未知(但特定)超类型。
传递给and()
Predicate<T>
方法的参数的要求是它必须能够测试T
类型的对象,所以它是有意义的一个Predicate<? super T>
。
因此,传递给l.getPredicate().and(...)
的类型必须是可以应用于? super String
的谓词,即可以应用于String
的某个未知超类型:最具体的类型是? super Object
。
(在整个过程中,我使用的是泛型术语中使用的惯例,类型T
被认为是自身的超类型,所以{&#34;超级类型T
&#34;我的意思是&#34; T
或其中一个超类&#34;等。)
请注意,生成的表达式的类型为Predicate<? super String>
,因此您可以执行
Predicate<? super String> and(FilteredList<String> l, Predicate<? super Object> predicate) {
return l.getPredicate().and(predicate);
}