Kotlin:基于函数返回值的未经检查的类型推断

时间:2018-04-19 09:11:45

标签: kotlin type-inference

在Java中,你可以编写像这样的方法,它不会抛出任何强制转换警告,并根据返回类型推断出类型:

public static <T> T getService(final String name) {
    return (T) appCtx.getBean(name);
}

以下是一些使用示例:

public static StatusService getStatusService() {
    return getService("statusService");
}

public static VenueService getVenueService() {
    return getService("venueService");
}

现在我尝试将其转换为Kotlin并想出了这个:

fun <T> getService(name: String): T {
    return appCtx?.getBean(name) as T
}

但是我在这里得到了警告:

Unchecked cast: Any? to T

好的,在浏览Stackoverflow之后我发现你可以用注释将其关闭:

@Suppress("UNCHECKED_CAST")

我不确定这是一个干净的解决方案。

我的问题是:当您通过Kotlin中的返回类型推断出类型时,有没有办法避免这种未经检查的类型转换警告?如果是这样,你怎么能这样做。

更新1

在一些答案和评论(https://stackoverflow.com/a/49918740/2735286和Marko Topolnics&#39;评论)之后,我将代码更改为:

inline fun <reified T> getService(name: String): T {
    requireNotNull(appCtx) { "Application context has not been set." }
    return appCtx?.getBean(name) as T
}

此代码消除了未经检查的强制转换警告,并提供了改进的错误处理。

更新2

在Alexey Romanov的建议之后,我删除了requireNotNull并将代码更改为:

var appCtx: ApplicationContext by Delegates.notNull()

private inline fun <reified T> getService(name: String): T {
    return appCtx.getBean(name) as T
}

2 个答案:

答案 0 :(得分:3)

实际上即使是java编译器(至少从JDK 8u131开始)也会发出类似的警告。所以kotlinc遵循相同的道路。

答案 1 :(得分:2)

这就是演员未经检查的原因,而Kotlin的警告是正确的:

// Java
Object service = <StatusService> getService("venueService");

你会注意到它编译并且在执行时不会抛出异常。这是因为类型擦除将(T) appCtx.getBean(name)转换为(Object) appCtx.getBean(name),这种转换显然总是成功。

reified T不会发生这种情况,因为在调用网站上已知T,因此会检查其中的广告。