下面的测试类,通过。
class SimpleClassTest {
private inline fun <reified T> anyObject(): T {
return Mockito.anyObject<T>()
}
lateinit var simpleObject: SimpleClass
@Mock lateinit var injectedObject: InjectedClass
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun testSimpleFunction() {
simpleObject = SimpleClass(injectedObject)
simpleObject.simpleFunction()
verify(injectedObject).settingDependentObject(anyObject())
}
}
但如果我们改变
private inline fun <reified T> anyObject(): T {
return Mockito.anyObject<T>()
}
到
private inline fun <reified T: Any> anyObject(): T {
return Mockito.anyObject<T>()
}
会失败
java.lang.IllegalStateException: Mockito.anyObject<T>() must not be null
Kotlin中<reified T>
与<reified T: Any>
的区别是什么?
已更新
如果Any为非null,则使用<reified T: Any>
不应返回错误,因为settingDependentObject(...)
被声明为接收非null参数。我希望<reified T>
应该出错,但它与我的理解相反。
我明白了什么不对吗?
答案 0 :(得分:7)
作为stated in the documentation和the linked answer,默认上限为Any?
。换句话说,以下声明是等效的:
inline fun <reified T> anyObject(): T = Mockito.anyObject<T>()
inline fun <reified T:Any?> anyObject(): T = Mockito.anyObject<T>()
Mockito.anyObject<T>()
和T:Any
的{{1}} will return null
。当调用返回类型为T:Any?
的方法时,Mockito返回的T:Any
值无法通过Kotlin编译器插入的运行时检查。在调用null
之前,会抛出您收到的错误。
答案 1 :(得分:3)
当您在类型参数上添加T : Any
约束时,您实际上将其设为非空:T
是Any
的子类型且Any
无法保留空值。
由于函数是内联函数并且具有reified类型参数,因此该参数将替换为真正的非可空类型。因此,在呼叫站点上执行空检查,因此您将获得此异常。