提问者:小点点

静态编程语言:基于函数返回值的未检查类型推断


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
}

共2个答案

匿名用户

实际上,即使java编译器(至少JDK8u131)也会发出类似的警告。所以kotlinc遵循同样的路径。

匿名用户

这就是为什么强制转换没有被选中,静态编程语言的警告是正确的:

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

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

这不会发生在具体化的T中,因为T在调用站点是已知的,因此检查了那里的强制转换。