一个奇怪的generics边缘情况与Mockito.when()和generics类型推断
我正在编写一个使用Mockito的java.beans.PropertyDescriptor
测试用例,我想模仿getPropertyType()
的行为来返回一个任意的Class
对象(在我的例子中, String.class
)。 通常,我会通过调用:
// we already did an "import static org.mockito.Mockito.*" when(mockDescriptor.getPropertyType()).thenReturn(String.class);
然而,奇怪的是,这不编译:
cannot find symbol method thenReturn(java.lang.Class)
但是当我指定类型参数而不是依赖于推理时:
Mockito.<Class>when(mockDescriptor.getPropertyType()).thenReturn(String.class);
一切都很笨拙。 为什么编译器在这种情况下无法正确推断when()的返回类型? 我之前从未必须指定参数。
PropertyDescriptor#getPropertyType()
返回Class>
的对象,其中?
意思是“这是一种类型,但我不知道它是什么”。 我们称这种类型为“X”。 因此, when(mockDescriptor.getPropertyType())
创建OngoingStubbing
,其方法thenReturn(Class
只能接受Class
对象。 但编译器不知道这个“X”是什么类型,所以它会抱怨你传入任何类型的Class
。 我认为这与编译器抱怨在Collection>
上调用add(...)
原因相同。
当你为when
方法的类型显式指定Class>
when
,你并不是说mockDescriptor.getPropertyType()
返回一个Class>
,你说when
返回一个OngoingStubbing
。 然后,编译器检查以确保when
类型与Class>
匹配when
传入的内容; 因为getPropertyType()
返回我前面提到的“ Class
”,它当然与你指定的Class>
匹配。
所以基本上
// the inferred type is Class<"some type"> Mockito.when(mockDescriptor.getPropertyType()) // the specified type is Class<"any type"> Mockito.>when(mockDescriptor.getPropertyType())
在我的IDE中,原始代码的错误消息是
The method thenReturn(Class) in the type OngoingStubbing> is not applicable for the arguments (Class)
capture#1-of ?
是我上面描述的“X”。