generics - Java 8 中的谓词接口(interface)

标签 generics java-8 predicate

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;

因为IntegerLongNumber 的子类型,我们可以这样做:

p1 = p3;
p1 = p4;

同时,我们假设 p3p4不为空。他们在测试中可以接受的唯一类型是 IntegerLong .

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/

相关文章:

java - 将泛型 T 转换为 Object[]

c# - C#泛型的属性限制

java - 为什么 Java 8 的 Predicate<T> 不扩展 Function<T, Boolean>

Java - 将属性与逻辑介词相关联

java - 从同一数组创建两个列表,修改一个列表,更改另一个

java - 为什么不用导入就可以使用Predicate参数?

java - 为什么不允许使用instanceof,但在泛型中允许使用Class.isInstance()?

generics - 如何在结构/特征、常规变量声明和函数中最好地实现泛型?

java - Java 8 中查询结果数据库的最优化方式

java - Google AppEngine中的JSP是否支持JDK1.8