我无法理解' instanceOf'的方法签名。 hamcrest包中的方法。这是方法
public static <T> Matcher<T> instanceOf(Class<?> type) {
return (Matcher<T>) new IsInstanceOf(type);
}
我可以理解返回类型是Matcher <T>
,第一个<T>
声明泛型。但是T
永远不会在方法中推断出来。请注意,我们不会将T
作为参数类型传递。
出现了一个问题:它是否意味着T
是无界的,我们可以动态地将Matcher返回到任何类型?
答案 0 :(得分:1)
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}}
答案 1 :(得分:0)
我认为这个问题的答案很简单。由于类型参数T
未在instanceOf
方法的任何参数中使用,因此允许编译器推断任何类型以用作该方法的类型参数呼叫。因此,编译器总是可以推断出&#34;工作的类型&#34;在方法调用的上下文中(简单来说)。
这一切只意味着像
这样的一行assertThat(something, instanceOf(Some.class));
将始终键入check,无论something
的静态类型如何,因为编译器会将T
推断为something
的静态类型,assertThat
以及instanceOf
电话。
这是一件好事,因为该行的重点是检查something
的动态类型,这是静态不知道的。如果something
的确切类型是静态知道的,那么这个断言甚至是不必要的。