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");
}
现在我试图将其转换为静态编程语言,并得出了这个:
fun <T> getService(name: String): T {
return appCtx?.getBean(name) as T
}
但在这里,我得到了一个石膏警告:
Unchecked cast: Any? to T
好的,在浏览了Stackoverflow之后,我发现你可以用注释关闭它:
@Suppress("UNCHECKED_CAST")
不过,我不确定这是一个干净的解决方案。
我的问题是:当您通过静态编程语言中的返回类型推断类型时,有没有办法避免这种未经检查的类型强制转换警告?如果是,您如何做到这一点。
更新1
在一些答案和评论(https://stackoverflow.com/a/49918740/2735286和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的建议之后,我删除了要求NotNull
并将代码更改为:
var appCtx: ApplicationContext by Delegates.notNull()
private inline fun <reified T> getService(name: String): T {
return appCtx.getBean(name) as T
}
实际上,即使java编译器(至少JDK8u131)也会发出类似的警告。所以kotlinc遵循同样的路径。
这就是为什么强制转换没有被选中,静态编程语言的警告是正确的:
// Java
Object service = <StatusService> getService("venueService");
您会注意到它会编译并且在执行时不会抛出异常。这是因为类型擦除将(T)appCtx. getBean(name)
转换为(Object)appCtx.getBean(name)
并且此强制转换显然总是成功的。
这不会发生在具体化的T
中,因为T
在调用站点是已知的,因此检查了那里的强制转换。