Soy nuevo en Java, aprendiendo el framework Hamcrest.

He leído el código de la interfaz Matcher y no entiendo el comentario y la firma del método de matches(Object actual). Esperaba que fuera matches(T actual), y use el tipo genérico T en lugar de Object que acepta todo.

Este es el código fuente: https: // github. com / hamcrest / JavaHamcrest / blob / master / hamcrest / src / main / java / org / hamcrest / Matcher.java

Para el método matches:

public interface Matcher<T> extends SelfDescribing {

/**
     * Evaluates the matcher for argument <var>item</var>.
     *
     * This method matches against Object, instead of the generic type T. This is
     * because the caller of the Matcher does not know at runtime what the type is
     * (because of type erasure with Java generics). It is down to the implementations
     * to check the correct type.
     *
     * @param actual the object against which the matcher is evaluated.
     * @return <code>true</code> if <var>item</var> matches, otherwise <code>false</code>.
     *
     * @see BaseMatcher
     */
    boolean matches(Object actual);

Leer el comentario sobre el método muestra que esto es por intención y no entiendo por qué. Sé lo que es tipo borrado en java. Pero aún no entiendo por qué el diseñador de Hamcrest pensó que es mejor tener Object como entrada en lugar de tipo genérico para la interfaz que se declara como genérica public interface Matcher<T> extends SelfDescribing

0
Eliyahu Machluf 12 feb. 2020 a las 12:11

2 respuestas

La mejor respuesta

Q:

No entiendo por qué.

A: (de JavaDocs)

Esto se debe a que la persona que llama al Matcher no sabe en tiempo de ejecución cuál es el tipo (debido a la eliminación de tipo con genéricos de Java). Depende de las implementaciones verificar el tipo correcto.

También de JavaDocs:

Cuando se utiliza Hamcrest, no hay garantía de con qué frecuencia se llamará matches() o describeMismatch()

Tienes que echar un vistazo a la implementación Hamcrest-Libs.
Entonces, su implementación matches() es llamada internamente por Hamcrest (con cualquier Objeto). En tiempo de ejecución, Hamcrest no tiene oportunidad de saber (¡y encontrar!) El método correcto matches(...), porque los genéricos fueron borrados. Debe comprobarlo usted mismo si el objeto pasado (por Hamcrest) realmente coincide. Esto no tiene mucho que ver con Hamcrest.

¡Salud!

0
Ben 13 feb. 2020 a las 14:58

Tienes razón, esperarías T al principio en lugar de Object, pero sabiendo que los genéricos son una función de tiempo de compilación y no están disponibles durante el tiempo de ejecución (cuando las pruebas se ejecutan y necesitan el emparejador) (ver Type Erasure) tiene sentido resaltar el hecho de que técnicamente podría ser algo que no es T, lo que le obliga a verificar para crear mensajes de error más claros en ese caso.

Tipo de borrado (parafraseado de Oracle):

El borrado de tipo asegura que no se generen clases adicionales para diferentes genéricos. Eso

  • reemplaza todos los tipos genéricos por su límite u objeto.
  • introduce moldes automáticos
  • crea métodos adaptadores para preservar el polimorfismo.

Para que no haya sobrecarga de tiempo de ejecución.

1
Nicktar 12 feb. 2020 a las 09:54