Java finally和write-after-catch的区别

Java finally和write-after-catch的区别,java,exception,try-catch,try-catch-finally,Java,Exception,Try Catch,Try Catch Finally,“finally”和“catch”之后的write有什么区别 例如: public boolean example() { try { // Code } catch (RuntimeException e) { // Code } finally { return true; } } public boolean example() { try { // Code } catch

“finally”和“catch”之后的write有什么区别

例如:

public boolean example() {
    try {
        // Code
    } catch (RuntimeException e) {
        // Code
    } finally {
        return true;
    }
}

public boolean example() {
    try {
        // Code
    } catch (RuntimeException e) {
        // Code
    } 
    return true;
}

你的情况没有什么不同。但是

无论try块中发生了什么,运行时系统始终在中执行语句

所以这是进行清理的最佳场所


请注意,如果您使用的是JDK 7+,那么finally块的大多数用法都可以消除,只需在您提供的代码中使用一个。

就可以了。但是finally用于在try块之后运行一些代码,不管是否存在异常

这里要指出的有趣的一点是,我们应该避免从finally块返回,因为当我们从try块返回某些内容时,它会在场景中造成混乱。考虑这段代码:

try {
    return true;
}
finally {
    return false;
}
现在,无论try中发生什么,该代码都将返回false。在许多方面,这种行为与对finally含义的通俗理解完全一致——“无论try块中事先发生了什么,始终运行此代码。”因此,如果从finally块返回true,则总体效果必须始终是返回true,不是吗

一般来说,这很少是一个好习惯用法,你应该最后使用它 为清理/关闭资源而大量阻塞,但很少 从它们返回一个值

只要我们希望执行某行代码,即使发生异常,也可以使用finally()
但是如果你在catch之后写一行代码,如果发生异常,它将不会执行。

首先,唯一可以被认为是候选的习惯用法是:

注意捕获的类型。只有捕获到任何可能的异常,包括
ThreadDeath
VirtualMachineError
等黑暗怪物,您才能希望无条件地到达try catch下面的代码

但是,这只是开始。如果处理代码本身抛出异常怎么办?所以你至少需要

try { 
    // main stuff
} catch (Throwable t) {
    try { 
        // handle 
    } catch (Throwable t) { 
        // no code allowed here! Otherwise we descend into
        // infinite recursion
    }
}
// finally stuff
现在,您可能终于开始意识到
的好处,但这还不是全部。考虑一个非常典型的场景:

try { 
  // main stuff, may throw an exception. I want the exception to
  // break what I'm doing here and propagate to the caller.
  return true;
} finally { 
    // clean up, even if about to propagate the exception 
}

你怎么重写这个?如果没有代码复制,这是不可能的。

在这个问题中要理解的第一件事是“为什么我们使用try{}catch{}block”Ok

答案是,当我们的代码有可能抛出异常时

我们在try{…}block& catch{…}块包含捕获try{}块中代码生成的异常的代码

最后,{…}块包含在try{}catch{}块抛出异常时,try{}catch{}块之后立即执行的代码


e、 g当你访问某个网站,但对某个服务器端的问题做了处理,它无法显示页面上的某种消息,如“404错误或服务器正在更新”,这些代码都写在finally块中。

这个简单的catch只用于catch异常并对其进行处理,但最后,如果异常与否,则执行,例如,对于紧密连接。

我们使用try块、catch块和finally块来处理程序中的异常。程序可能有检查或未检查的异常。因此,此块用于处理这些异常。在try块中,我们提到或编写可能导致异常的代码,如果我们希望在异常发生时运行代码,那么我们在catch块中编写这些代码。finally是一个非常特殊的块,它给了我们一个特殊的特性,如果catch块没有运行,那么在程序终止之前,finally块代码肯定会执行。这主要用于在不需要的程序终止期间保存数据。如果我们使用try块,那么try块之后必须有catch块,但finally是可选的,不是强制性的。

finally块对于清理代码非常有用,就像关闭打开的流一样

例如:


由于您的代码只返回
true/false
,因此不会产生太大影响。但是,考虑一下任何其他代码/逻辑,其中一些强制/清除代码是编写来执行的

此外,通过我们的代码捕获所有异常也很困难,或者换句话说,我们应该捕获我们可以处理的特定异常。在这一点上,
最终将成为真正的救世主,因为它将始终执行(除了
System.exit()
或在某些递归情况下)

此外,为了使代码保持一致性,应该始终使用
finally
块来执行任何清理代码

您也可以参考以下帖子以了解更多说明:

第一种情况:

如果try块中发生异常,则将执行catch块;如果再次发生异常,则在为同一catch块提供服务时,将执行finally块。

第二种情况:


如果try块中发生异常,则将执行catch块,如果同一catch块中还有其他异常,则将执行“return true;”。

您可以添加逻辑来关闭
finally
块语句中的资源,并在此处获得异常,因此最好的替代方法是后者(IMO).你的例子没有什么不同。在最后做一些清理,无论如何都会执行。这完全是错误的。代码在try-catch之后执行。如果通过返回或抛出异常最终突然终止,则忽略函数调用之前的任何返回。这意味着,如果抛出异常或使用return,finally将吞下任何异常或普通返回值。如上所述,仅将finally用于资源清理,并且要注意,如果您在finally中调用可能引发异常,则应该将它们包装在try-catch中,以避免吞并其他异常。如果使用try with resources,则可以通过Throwable.getSuppressed()获得被吞没的异常
try { 
  // main stuff, may throw an exception. I want the exception to
  // break what I'm doing here and propagate to the caller.
  return true;
} finally { 
    // clean up, even if about to propagate the exception 
}
    File f = new File("\file.txt");
    FileStream fs;
    try{
       fs = new FileStream(f);
    } catch (IOException ioe){
       ioe.printStackTrace();
    } finally {
      if (fs != null) {
         fs.close() // close the stream
      }
    }