Java 为什么要求返回值?

Java 为什么要求返回值?,java,Java,下面是示例代码,非常简单 Public String method_A() throws Exception{ try{ //do something here return "result"; }catch(Exception e){ **handleException(e);** } } private void handleException(Exception e) throws Exception{ lo

下面是示例代码,非常简单

Public String method_A() throws Exception{
    try{
      //do something here

       return "result";
    }catch(Exception e){
       **handleException(e);**   
    }
}

private void handleException(Exception e) throws Exception{
    log.error("", e);
    throw new Exception();
}
编译器抱怨方法_A没有返回值。我的理解是,因为在catch块中,方法handleException总是抛出异常,所以不需要返回值


我错过了什么吗?

Java编译器不知道handleException总是抛出异常。它只是认为您可以处理异常,而不是重新调用它。Java编译器没有遵循那么深的代码

然而,你做错了。你不应该对例外情况保持沉默。请这样做:

public String method_A() throws Exception {
    try {
        // do something here
        return "result";
    } catch(Exception e) {
        handleException(e);
        throw e;
    }
}

private void handleException(Exception e) {
    log.error("", e);
}
或者,除非您在其他地方使用handleException:

public String method_A() throws Exception {
    try {
        // do something here
        return "result";
    } catch(Exception e) {
        log.error("", e);
        throw e;
    }
}

由于您将该方法声明为公共字符串,这意味着Java希望您返回一个字符串。如果您没有return语句,或者它没有专门抛出异常,编译器将不喜欢它。它不会查看所有代码以查看是否每次都引发异常。

只有在try块引发异常时,catch块才会执行。因为不是这样,所以这里不会抛出异常


与此无关,Java要求您指定一个显式返回值,即使您认为函数中的所有代码路径都会引发异常。虽然编译器可以在简单的情况下找到答案,但C编译器可以做到这一点,例如,理论上,编译器不可能证明不存在非抛出的代码路径。

仅仅因为处理异常并不意味着抛出异常,或者至少编译器是这样认为的

如果您的try块失败,并且您正在外部处理异常,那么您的方法很可能不会返回任何内容,因此编译将无法防止混乱的错误

回答我认为是你问题的关键:代码没有编译,因为编译器不会单步执行到你的另一个方法来查看它是否在那里抛出异常。必须从方法中抛出异常,编译器才能看到它

请尝试将其内联:

public String method_A throws Exception{
    try{
        //do something here
        return "result";
    }catch(Exception e){
        log.error("", e);
        throw e;
    }
}

编译器会抱怨,因为它在方法末尾看不到返回。try中的代码是限定范围的。它并没有真正告诉编译器方法是否将返回一个值。若代码在返回之前抛出异常,它将被传输到catch。通常,在方法末尾返回null毕竟if,try-ends会使编译器感到高兴。事实上,在eclipse中,如果您使用指定的返回类型编写方法,您会注意到编译器告诉您的第一件事是在编写单行代码之前返回值。这就是在方法末尾需要返回值的主要原因。

处理异常!=抛出异常。感谢您的快速响应!是的,我明白。我想说的是handleException总是抛出异常,所以编译器应该理解吗?编译器只知道带有throws声明的方法,因为它们可能抛出异常。一般来说,确定给定的方法是否会引发异常是一个无法确定的问题,因此编译器不会对此进行检查,即使在看起来很清楚的情况下也是如此。在handleException声明中不再需要throws子句。是的,我知道它会起作用。我们将它放在一个单独的私有方法中的原因是,实际上异常处理要复杂得多,我们不希望它无处不在。但是您仍然需要在catch子句中重新调用,而不是在handleException中。您无法改变。如果handleException需要在重新引发异常之前修改异常,您也可以让它返回异常,由调用代码块引发。感谢所有响应!嗯,这是我最喜欢的。嗯,我希望Java编译器更聪明一点,我想说的也不算太多……你刚刚扔掉了异常处理的因式分解:因式分解可以很好地避免重复代码。@Volune可能这取决于要执行的次数:但是,结构本身有点混乱,所以我试图解决这个问题。你的措辞也令人困惑。return语句可以完成方法调用,throw语句也可以完成方法调用。所以,不管方法里面有什么是错误的。考虑更新你的答案。我仍然没有看到投票失败的原因。我花时间用我的实践经验来解决与此相关的问题,结果我被否决了。