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
2 respuestas
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()
odescribeMismatch()
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!
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.
Nuevas preguntas
java
Java es un lenguaje de programación de alto nivel. Utilice esta etiqueta cuando tenga problemas para usar o comprender el idioma en sí. Esta etiqueta rara vez se usa sola y se usa con mayor frecuencia junto con [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] y [maven].