Kotlin中<reified t:=“”any =“”>与<reified t =“”>有什么不同?

时间:2016-05-23 00:22:28

标签: mockito kotlin

下面的测试类,通过。

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>应该出错,但它与我的理解相反。

我明白了什么不对吗?

2 个答案:

答案 0 :(得分:7)

作为stated in the documentationthe 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约束时,您实际上将其设为非空:TAny的子类型且Any无法保留空值。

由于函数是内联函数并且具有reified类型参数,因此该参数将替换为真正的非可空类型。因此,在呼叫站点上执行空检查,因此您将获得此异常。