Kotlin:基于函数 return 值的未经检查的类型推断
Kotlin: unchecked type inference based on function return value
在 Java 中,您可以编写这样的方法,它不会抛出任何转换警告并根据 return 类型推断类型:
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
好的,在 Whosebug 上浏览了一些之后,我发现你可以用注释关闭它:
@Suppress("UNCHECKED_CAST")
虽然我不确定这是一个干净的解决方案。
我的问题是:当您通过 Kotlin 中的 return 类型推断类型时,有没有办法避免这种未经检查的类型转换警告?如果可以,你怎么做。
更新 1
经过一些回答和评论( 和 Marko Topolnics 的评论)后,我将我的代码更改为:
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
}
实际上甚至 java 编译器(至少从 JDK 8u131 开始)也会发出类似的警告。所以 kotlinc 遵循相同的路径。
这就是为什么未检查强制转换而 Kotlin 的警告是正确的原因:
// Java
Object service = <StatusService> getService("venueService");
您会注意到它编译并且在执行时不会抛出异常。这是因为类型擦除将 (T) appCtx.getBean(name)
变成了 (Object) appCtx.getBean(name)
并且这种转换显然总是成功的。
reified T
不会发生这种情况,因为 T
在调用站点是已知的,因此会检查那里的转换。
在 Java 中,您可以编写这样的方法,它不会抛出任何转换警告并根据 return 类型推断类型:
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
好的,在 Whosebug 上浏览了一些之后,我发现你可以用注释关闭它:
@Suppress("UNCHECKED_CAST")
虽然我不确定这是一个干净的解决方案。
我的问题是:当您通过 Kotlin 中的 return 类型推断类型时,有没有办法避免这种未经检查的类型转换警告?如果可以,你怎么做。
更新 1
经过一些回答和评论(
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
}
实际上甚至 java 编译器(至少从 JDK 8u131 开始)也会发出类似的警告。所以 kotlinc 遵循相同的路径。
这就是为什么未检查强制转换而 Kotlin 的警告是正确的原因:
// Java
Object service = <StatusService> getService("venueService");
您会注意到它编译并且在执行时不会抛出异常。这是因为类型擦除将 (T) appCtx.getBean(name)
变成了 (Object) appCtx.getBean(name)
并且这种转换显然总是成功的。
reified T
不会发生这种情况,因为 T
在调用站点是已知的,因此会检查那里的转换。