Tipos de argumentos que se pasan a <? Super T> en Java

Holmes Queen:

En el capítulo 8 de los tipos genéricos de volumen del núcleo de Java I Edición 10,

NOTA: Otro uso común de los límites del supertipo es un tipo de argumento de una interfaz funcional. Por ejemplo, la interfaz Collection tiene un método

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

El método elimina todos los elementos que cumplen el predicado dado. Por ejemplo, si no le gusta a los empleados con códigos hash impares, se pueden quitar así:

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

¿Quieres ser capaz de pasar una Predicate<Object>, no sólo una Predicate<Employee>. El súper comodín hace posible.

Me encontré con algunos problemas cuando se trata de entender esto, por lo que <? super E>los medios de filtro que podrían apuntar a cualquier tipo de predicados que pueden ser superclase de Employeeo Employeesí.

El texto anterior se menciona que podría pasar una Predicate<Object>a Predicate<? super E>.

Pero lo que si Predicate<? super E>los puntos a Predicate<Employee>, puede Predicate<Object>ser pasado a Predicate<Employee>?

¿He entendido mal algo?

AVI:

Su comprensión es correcta. Por ejemplo, una función que toma Predicate<? super Employee>(como en el ArrayList<Employee>ejemplo) también puede aceptar un Predicate<Object>igual Objects::nonNull. Conceptualmente, esto tiene sentido por la siguiente razón: "Nosotros (la clase) tomamos una Predicateque opera en nosotros, o en cualquiera de los (transitivo) superclases de nosotros mismos, porque tenemos un es-una relación con esos superclases." Es decir, una función que toma cualquier Objecty devuelve una booleanes equivalente, aplicable a Employeecausa Employee is-a Object , y por lo que es válido aplicar esta función aEmployee. La clase derivada no es exactamente el mismo que la clase base, pero el predicado (prueba lógica) todavía se aplica a la clase derivada, porque tiene sentido hablar de la clase derivada as-a clase base.

Vamos a ir a través de un ejemplo: Employeesse podría derivar de Person. Si Personse puede probar con una Predicate<Person>llama hasJob, entonces es lógicamente suena para ser capaz de prueba Employeespara hasJobasí. La capacidad de esa función para tomar Predicate<? super Employee>en lugar de sólo Predicate<Employee>es necesaria para mantener la capacidad de la función para tomar un predicado lógicamente sonido. Por otro lado, si sólo se espera de Employees para hacerse la prueba de alguna propiedad, es posible aceptar solamente una Predicate<Employee>vez, ya que corresponde a la solidez lógica de solo Employeey sus clases derivadas que poseen la capacidad de hacerse la prueba de esa propiedad.

Para ser 100% claro sobre lo que está pasando aquí:

  • Predicate<? super Employee>acepta Predicateque tests Employeey cualquier superclase de Employee, incluyendo Object
  • Predicate<Employee>acepta Predicateque tests Employeey cualquier subclase de Employee, que excluye Object

Teniendo en cuenta esta jerarquía de clases: SalariedEmployee is-a Employee is-a Person, esto es lo que sucede (P es la abreviatura de Predicate):

╔══════════════════╦═══════════╦═══════════════════╦═════════════╦═════════════════════╦═════════════════════╦═════════════════════════════╗
║       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                      ║
╚══════════════════╩═══════════╩═══════════════════╩═════════════╩═════════════════════╩═════════════════════╩═════════════════════════════╝

Nota que Accept/Rejectdenotan los tipos que se pueden alimentar en el Predicate, no el resultado real de la Predicate.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=314503&siteId=1
Recomendado
Clasificación