要传递给 <?超级 T> 在 Java

Types of argument to be passed to <? super T> in Java

核心泛型类型第 8 章 Java 第一卷第 10 版,

NOTE: Another common use for supertype bounds is an argument type of a functional interface. For example, the Collection interface has a method

default boolean removeIf(Predicate<? super E> filter)

The method removes all elements that fulfill the given predicate. For example, if you hate employees with odd hash codes, you can remove them like this:

ArrayList<Employee> staff = . . .; Predicate<Object> oddHashCode = obj -> obj.hashCode() %2 != 0; staff.removeIf(oddHashCode);

You want to be able to pass a Predicate<Object>, not just a Predicate<Employee>. The super wildcard makes that possible.

我在试图理解这一点时遇到了一些问题,所以 <? super E> 意味着过滤器可以指向可以是 EmployeeEmployee 本身的超类的任何谓词类型。

上面的文字提到我们可以将Predicate<Object>传递给Predicate<? super E>

但是如果Predicate<? super E>指向Predicate<Employee>Predicate<Object>可以传递给Predicate<Employee>吗?

我是不是误会了什么?

您的理解是正确的。例如,采用 Predicate<? super Employee> 的函数(如您的 ArrayList<Employee> 示例)也可以接受 Predicate<Object>,例如 Objects::nonNull。从概念上讲,这是有道理的,原因如下: "We (the class) take a Predicate that operates on us, or on any of the (transitive) superclasses of ourself, because we have an is-a relationship with those superclasses." 也就是说,一个函数取任何 Object 和 returns 一个 boolean 等价地适用于 Employee 因为Employee 是-a Object,所以把这个函数应用到Employee上是有效的。派生class与基class并不完全相同,但谓词(逻辑测试)仍然适用于派生class,因为谈论派生[=是有意义的81=] 作为基础 class。

让我们来看一个例子:Employees 可以派生自 Person。如果 Person 可以用名为 hasJobPredicate<Person> 进行测试,那么在逻辑上也可以为 hasJob 测试 Employees。该函数采用 Predicate<? super Employee> 而不仅仅是 Predicate<Employee> 的能力是维持函数采用逻辑上合理的谓词的能力所必需的。另一方面,如果您只期望 Employee 会针对某些 属性 进行测试,您可能只接受 Predicate<Employee>,因为这对应于仅 [=] 的逻辑合理性18=] 及其派生的 classes 具有针对 属性.

进行测试的能力

要 100% 清楚这里发生的事情:

  • Predicate<? super Employee> 接受 Predicate 那个 tests Employee[=18 的任何超级 class =], 包括 Object
  • Predicate<Employee> 接受 Predicate testEmployee [=18 的任何子 class =],其中 排除 Object

给定此 class 层次结构:SalariedEmployee is-a Employee is-a Person,这是发生的情况(Predicate 的 P 是 shorthand):

╔══════════════════╦═══════════╦═══════════════════╦═════════════╦═════════════════════╦═════════════════════╦═════════════════════════════╗
║       Type       ║ P<Person> ║ P<? super Person> ║ P<Employee> ║ P<? super Employee> ║ P<SalariedEmployee> ║ P<? super SalariedEmployee> ║
╠══════════════════╬═══════════╬═══════════════════╬═════════════╬═════════════════════╬═════════════════════╬═════════════════════════════╣
║ Person           ║ Accept    ║ Accept            ║ Reject      ║ Accept              ║ Reject              ║ Accept                      ║
║ Employee         ║ Accept    ║ Reject            ║ Accept      ║ Accept              ║ Reject              ║ Accept                      ║
║ SalariedEmployee ║ Accept    ║ Reject            ║ Accept      ║ Reject              ║ Accept              ║ Accept                      ║
║ Object           ║ Reject    ║ Accept            ║ Reject      ║ Accept              ║ Reject              ║ Accept                      ║
╚══════════════════╩═══════════╩═══════════════════╩═════════════╩═════════════════════╩═════════════════════╩═════════════════════════════╝

请注意 Accept/Reject 表示可以输入 Predicate 的类型,而不是 Predicate 的实际结果。