类型安全:从 Class<capture#2-of ?> 到 Class<? 的未经检查的强制转换 扩展 Throwable>

Hem*_*ang 0 java generics casting

我正在创建一个函数,我想在外部库中注册不同类型的异常。他们已经定义了一个接受 Class 作为参数的方法。

我想从配置中读取不同的异常并注册它,但是我收到类型转换警告。我可以忽略/抑制它,但是有什么办法不抑制它吗?

确切的警告是Type safety: Unchecked cast from Class<capture#2-of ?> to Class<? extends Throwable>

这是引发警告的示例代码

Class<?> exceptionClass = Class.forName("java.lang.Exception"); //Getting this value from Config. Let us assume that config is good and I get only valid classname which extends Throwable
registerExceptionInExternalLibrary((Class<? extends Throwable>)exceptionClass); // Getting the warning here
Run Code Online (Sandbox Code Playgroud)

我想我不能在这里进行铸造,因为没有对象。但如果我不使用转换,那么我会收到此警告

The method registerExceptionInExternalLibrary(Class<? extends Throwable>) in the type XXXXX is not applicable for the arguments (Class<capture#2-of ?>)

这是代码示例

Class<?> exceptionClass = Class.forName("java.lang.Exception"); //Getting this value from Config. Let us assume that config is good and I get only valid classname which extends Throwable
registerExceptionInExternalLibrary(exceptionClass); // Getting the warning here
Run Code Online (Sandbox Code Playgroud)

Kay*_*man 5

您可以为此使用Class.asSubClass 。

Class<?> exceptionClass = Class.forName("java.lang.Exception");
registerExceptionInExternalLibrary(exceptionClass.asSubclass(Throwable.class));
Run Code Online (Sandbox Code Playgroud)

该方法的完整代码如下所示,显示您只是将强制转换(和警告抑制)卸载到 JDK 方法,因此它没有什么神奇之处。但它在map()链条中非常方便,在这里也能很好地工作。它还确实验证您是否正在使用 进行正确的转换isAssignableFrom,如果您自己进行转换并抑制警告,那么您会忘记编写额外的功能。

@SuppressWarnings("unchecked")
public <U> Class<? extends U> asSubclass(Class<U> clazz) {
    if (clazz.isAssignableFrom(this))
        return (Class<? extends U>) this;
    else
        throw new ClassCastException(this.toString());
}
Run Code Online (Sandbox Code Playgroud)