and()
和or()
Java 8 中 Predicate 接口(interface)的方法采用 T
的任何父类(super class)型,即? super T
而不是? extends T
。我期望它能采用扩展 T
的任何类型。我这样思考的动机是,因为T
是我定义谓词的类型,复合谓词也应该位于 T
(即 T
的任何子类型)。 ? super T
背后的原因是什么? 。有人可以帮我理解吗?
最佳答案
这是我的理解。假设我们有这个:
interface MyPredicate<T> {
boolean test(T t);
}
以及这些声明:
MyPredicate<? extends Number> p1 = (Number n) -> n.intValue() > 9;
MyPredicate<Integer> p3 = null;
MyPredicate<Long> p4 = null;
因为Integer
和Long
是 Number
的子类型,我们可以这样做:
p1 = p3;
p1 = p4;
同时,我们假设 p3
和p4
不为空。他们在测试中可以接受的唯一类型是 Integer
和Long
.
p3.test(12);
p4.test(12L);
但是p1
会怎样?接受? Integer
,但是如果它指向 MyPredicate<Long>
该怎么办? ? Long
,但是如果它指向 MyPredicate<Integer>
该怎么办? ?
因此,除了 null
之外,没有办法将 p1 应用于任何其他内容。在这种情况下。
介绍一下p2
:
MyPredicate<? super Number> p2 = (Number n) -> n.intValue() > 10;
因为它使用super
我们甚至不能这样做:
p2 = p3; // will not compile
p2 = p4; // will not compile
但是这次我们知道我们将有一些类型 Number
因为它是 super 类型,所以我们可以在这里安全地应用 Number。含义:
p2.test(12); // 12 is Number
会编译得很好;因为我们 100% 确定无论是什么类型,它都是 Number 的父类(super class)型。
让我们改变MyPredicate
:
interface MyPredicate<T> {
boolean test(T t);
default MyPredicate<T> and(MyPredicate<? extends T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t); // this will not compile
}
}
因为我们使用了extends
,我们不知道实际类型,所以它会失败,不像 super
:
interface MyPredicate<T> {
boolean test(T t);
default MyPredicate<T> and(MyPredicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t); // compiles just file
}
}
关于generics - Java 8 中的谓词接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42779507/