了解如何修复Java未检查警告问题

了解如何修复Java未检查警告问题,java,generics,exception,lambda,Java,Generics,Exception,Lambda,我很难理解关于java泛型的两个声明之间的区别 假设我有以下两个接口 @functioninterface 公共接口检查功能{ R应用(T)抛出E; } 公共接口SomeInterface{ CheckedFunction firstFunction(); CheckedFunction secondFunction(); } 所以现在我创建了这些的一个实现,并弹出了一个“未检查”的警告,这正是我试图理解的 实现如下 public类TmpImpl实现了SomeInterface{ 最终Obj

我很难理解关于java泛型的两个声明之间的区别

假设我有以下两个接口

@functioninterface
公共接口检查功能{
R应用(T)抛出E;
}
公共接口SomeInterface{
CheckedFunction firstFunction();
CheckedFunction secondFunction();
}
所以现在我创建了这些的一个实现,并弹出了一个“未检查”的警告,这正是我试图理解的

实现如下

public类TmpImpl实现了SomeInterface{
最终ObjectMapper ObjectMapper=新ObjectMapper();
@凌驾
公共CheckedFunction firstFunction(){
返回objectMapper::writeValueAsString;
}
@凌驾
公共CheckedFunction第二个函数(){
返回json->objectMapper.readValue(json,TmpObj.class);
}
公共静态类TmpObj{
字符串s;
}
}
对于本例,我使用的是
com.fasterxml.jackson.databind.ObjectMapper
,因为它完全按照我的要求执行并生成警告

所以第一个函数现在有一个警告

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>
Unchecked覆盖:返回类型需要未经检查的转换。找到“CheckedFunction”,需要“CheckedFunction”
而第二个就可以了

为什么会这样?为了修复它,我显然遗漏了一些我没有注意到的东西


注意
JsonProcessingException
extends
IOException
(声明:
public class JsonProcessingException extends IOException

简单的回答是,您的实现是命令
JsonProcessingException
,而接口允许推断
E

换句话说,根据接口,这应该是可能的:

SomeInterface<String, RuntimeException> runtimeExceptionSomeInterface = null;
CheckedFunction<Object, String, RuntimeException> function = 
                     runtimeExceptionSomeInterface.firstFunction();
也就是说,您忽略了传入的
E
type参数,并将其强制替换为
JsonProcessingException


简而言之,如果希望
firstFunction()
是泛型的,那么相应地实现它:

@Override
public <E extends Throwable> CheckedFunction<Object, String, E> firstFunction() {
    return objectMapper::writeValueAsString;
}
如果采用以下方法实施,将解决问题:

class TmpImpl implements SomeInterface<TmpObj, IOException> {
    //...
    @Override
    public CheckedFunction<Object, String, IOException> firstFunction() {
        return objectMapper::writeValueAsString;
    }

也就是说,
SomeInterface
及其实现知道要处理的异常的范围,因此它们返回的函数知道,在这种情况下,
IOException
(之所以选择它,是因为您知道它包括
JsonProcessingException
,以及其他类型)

为什么在
firstFunction
上参数化
?我想展示一下区别。如果我把泛型作为参数(E),它会抱怨未检查的,但是如果我在类(E2)上使用泛型,它不会。为什么你不尝试
公共接口SomeInterface{CheckedFunction firstFunction();CheckedFunction secondFunction();}
?那会有效的。我试图理解为什么参数不起作用@纳曼。我没有用2个接口+2个实现来做同样的例子,而是将它们组合在一起one@MichaelMichailidis因为你的接口需要一个方法级的类型提示来识别推理过程中正确的类型匹配。哦,很有趣。“我怀疑这导致了您的实现”,这一点您是对的,因为我试图对应该处理的异常进行“精细”控制,而不是一般的控制(如
抛出异常
)。据我所知,这是不可能做到的!谢谢你的回答
@Override
public <E extends Throwable> CheckedFunction<Object, String, E> firstFunction() {
    return objectMapper::writeValueAsString;
}
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;
    }
interface SomeInterface<DTO> {
    CheckedFunction<Object, String, IOException> firstFunction();
    //...
}

class TmpImpl implements SomeInterface<TmpObj> {

    //...

    @Override
    public CheckedFunction<Object, String, IOException> firstFunction() {
        return objectMapper::writeValueAsString;
    }
}