Why is it <T> Matcher <T> as the return type in the Hamcrest instanceOf instance method
I find it difficult to understand the signature of the instanceOf method method in the hamcrest package. Here is the method
public static <T> Matcher<T> instanceOf(Class<?> type) {
return (Matcher<T>) new IsInstanceOf(type);
}
I can understand that the return type is Matcher <T>, and the first one <T>declares a generic one. But it is Tnever displayed in a method. Please note that we do not pass Tas an argument type.
One question arises: does this mean that it is Tunlimited and we can dynamically discard the returned Matcher to any type?
+4
2 answers
Matcher, instanceOf, , ... , .
, Matcher .
, :
// <T> is inferred to be 'Object' here
Matcher<Object> objectMatcher = instanceOf(Integer.class);
// <T> is inferred to be 'Integer' here
Matcher<Integer> integerMatcher = instanceOf(Integer.class);
Matcher assertThat :
// succeeds and expectedly so
// Integer.class.isInstance(5) is true
assertThat(5, objectMatcher);
// succeeds and expectedly so
// Integer.class.isInstance(5) is true
assertThat(5, integerMatcher);
// fails, but only after asserting, by throwing an AssertionError at runtime
// Integer.class.isInstance(Double) is false;
// but we wouldn't have gotten this far had we used the right matcher
assertThat(5.5d, objectMatcher);
// fails at compile time; exactly what we want generics to offer us - compile time safety
assertThat(5.5d, integerMatcher);
// you can also do it this way
// if you wanted to force T instead of
// expecting the compiler to infer it for you based on the context
assertThat(5, IsInstanceOf.<Integer>instanceOf(Integer.class));
assertThat, , T ( T , instanceOf!) ? super T, :
public static <T> void assertThat(T actual, Matcher<? super T> matcher)
// actual would be Integer and matcher would be Matcher<Object>
assertThat(5, objectMatcher);
// actual would be Integer and matcher would be Matcher<Integer>
assertThat(5, integerMatcher);
// actual would be Double and matcher would be Matcher<Object>
assertThat(5.5d, objectMatcher);
// actual would be Double and matcher would be Matcher<Integer>; see the mismatch?
assertThat(5.5d, integerMatcher);
+1