Reputation: 1401
I'm new to Java, learning Hamcrest framework.
I've read the code of the Matcher interface, and I don't understand the comment and the method signature of matches(Object actual)
. I expected it to be matches(T actual)
, and use the generic type T
instead of Object
which accept everything.
This is the source code: https://github.com/hamcrest/JavaHamcrest/blob/master/hamcrest/src/main/java/org/hamcrest/Matcher.java
for the matches
method:
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);
Reading the comment above the method, shows this is by intention, and I don't understand why. I know what is type erasure in java. But still I don't understand why the designer of Hamcrest thought it is better to have Object as input rather than generic type for interface which is declared to be generic
public interface Matcher<T> extends SelfDescribing
Upvotes: 1
Views: 275
Reputation: 3518
Q:
I don't understand why.
A: (from JavaDocs)
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.
also from JavaDocs:
When using Hamcrest, there is no guarantee as to how often
matches()
ordescribeMismatch()
will be called
You have to take a look at the Hamcrest-Libs implementation.
So, your matches()
implementation is called internally by Hamcrest (with any Object). At runtime, Hamcrest has no chance to know (and find!) the correct matches(...)
method, because the generics were cleared. You need to check yourself, if the object passed (by Hamcrest), really matches. This does not have much to do with Hamcrest.
Cheers!
Upvotes: 1
Reputation: 5575
You're right, you'd expect T
at first instead of Object
, but knowing that Generics are a compile time feature and not available during runtime (when the tests runs and needs the matcher) (see Type Erasure) it makes sense to highlight the fact that technically it could be something that's not T thus forcing you to check to create clearer error messages in that case.
Type Erasure (paraphrased from Oracle):
Type erasure makes sure that there are no additional classes generated for different generics. It
So that ther will be no runtime overhead.
Upvotes: 1