java - 了解如何修复的 Java 未经检查的警告问题
问题描述
我很难理解关于 java 泛型的两个声明之间的区别。
假设我有以下两个接口
@FunctionalInterface
public interface CheckedFunction<T, R, E extends Throwable> {
R apply(T t) throws E;
}
public interface SomeInterface<DTO, E2 extends Throwable> {
<E extends Throwable> CheckedFunction<Object, String, E> firstFunction();
CheckedFunction<String, DTO, E2> secondFunction();
}
所以现在我创建了一个实现,并弹出了一个“未经检查”的警告,这是我想要理解的。
实现如下
public class TmpImpl implements SomeInterface<TmpObj, IOException> {
final ObjectMapper objectMapper = new ObjectMapper();
@Override
public CheckedFunction<Object, String, JsonProcessingException> firstFunction() {
return objectMapper::writeValueAsString;
}
@Override
public CheckedFunction<String, TmpObj, IOException> secondFunction() {
return json -> objectMapper.readValue(json, TmpObj.class);
}
public static class TmpObj {
String s;
}
}
对于这个例子,我正在使用com.fasterxml.jackson.databind.ObjectMapper
它,因为它完全符合我的要求并生成警告。
所以 firstFunction 现在有一个警告
Unchecked overriding: return type requires unchecked conversion. Found 'CheckedFunction<java.lang.Object,java.lang.String,com.fasterxml.jackson.core.JsonProcessingException>', required 'CheckedFunction<java.lang.Object,java.lang.String,E>
而第二个很好。
为什么会这样?为了修复它,我显然遗漏了一些我没有注意到的东西!
注意JsonProcessingException
扩展IOException
(声明public class JsonProcessingException extends IOException
:)
解决方案
简短的回答是您的实现是口授JsonProcessingException
,而接口允许E
推断。
换句话说,根据界面,这应该是可能的:
SomeInterface<String, RuntimeException> runtimeExceptionSomeInterface = null;
CheckedFunction<Object, String, RuntimeException> function =
runtimeExceptionSomeInterface.firstFunction();
本声明:
<E extends Throwable> CheckedFunction<Object, String, E> firstFunction();
允许调用者为 指定具体参数E
,这正是我在上面的示例中所做的(使用RuntimeException
)。
但是,您的实现是静态强制的JsonProcessingException
:
public CheckedFunction<Object, String, JsonProcessingException> firstFunction() {
return objectMapper::writeValueAsString;
}
也就是说,您忽略了传入的E
类型参数并用JsonProcessingException
.
简而言之,如果您希望firstFunction()
是通用的,则相应地实现它:
@Override
public <E extends Throwable> CheckedFunction<Object, String, E> firstFunction() {
return objectMapper::writeValueAsString;
}
但是,上述失败return objectMapper::writeValueAsString;
并出现 unhandled JsonProcessingException
,我怀疑这导致了您的实施。
这仅仅意味着您使用泛型Throwable
参数是错误的。
解决它的第一次尝试是使用SomeInterface
'E2
变量:
interface SomeInterface<DTO, E2 extends Throwable> {
CheckedFunction<Object, String, E2> firstFunction();
CheckedFunction<String, DTO, E2> secondFunction();
}
如果使用以下方法实现,这将解决问题:
class TmpImpl implements SomeInterface<TmpObj, IOException> {
//...
@Override
public CheckedFunction<Object, String, IOException> firstFunction() {
return objectMapper::writeValueAsString;
}
但是,您仍然会遇到问题,因为SomeInterface
知道将引发什么异常的不是用户,而是实现。这意味着您应该在 API 上声明异常类型,而不是使其成为通用参数:
interface SomeInterface<DTO> {
CheckedFunction<Object, String, IOException> firstFunction();
//...
}
class TmpImpl implements SomeInterface<TmpObj> {
//...
@Override
public CheckedFunction<Object, String, IOException> firstFunction() {
return objectMapper::writeValueAsString;
}
}
也就是说,SomeInterface
它的实现知道要处理的异常范围,因此它们返回的函数知道,在这种情况下,IOException
(选择它是因为你知道它包括JsonProcessingException
,以及其他类型)
推荐阅读
- flutter - 参数类型“ShowSnackBar”不能分配给参数“SnackBar”
- ruby-on-rails - 我无法在 ruby 中加载库
- google-apps-script - .addFile 似乎已被弃用,我还能使用什么其他方法?
- python - 选择重复的相同字符
- ruby-on-rails - 上午下午而不是 24 小时在轨道上的人性化时间?
- python - ValueError:缓冲区 dtype 不匹配,预期为“double”,但得到“float”
- r - 如何创建相关性 = 0.25 的数值向量?
- java - 使用 android 平板电脑和 HC-05 无线电发射器从蓝牙输入流中提取数据的问题
- flutter - 未处理的异常:类型'ImmutableMap
' 不是类型 'List 的子类型 ' 在类型转换中 - python - sklearn 交叉验证 R^2 分数与使用训练模型对训练和验证数据进行的手动检查不匹配