为什么我们使用finally块?

发布于 2024-09-12 23:57:57 字数 311 浏览 6 评论 0原文

据我所知,以下两个代码片段都具有相同的目的。为什么要有 finally 块?

代码A:

try { /* Some code */ }
catch { /* Exception handling code */ }
finally { /* Cleanup code */ }

代码B:

try { /* Some code */ }
catch { /* Exception handling code */ }
// Cleanup code

As far as I can tell, both of the following code snippets will serve the same purpose. Why have finally blocks at all?

Code A:

try { /* Some code */ }
catch { /* Exception handling code */ }
finally { /* Cleanup code */ }

Code B:

try { /* Some code */ }
catch { /* Exception handling code */ }
// Cleanup code

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

断爱 2024-09-19 23:57:57
  • 如果抛出您未处理的异常会发生什么? (我希望你没有捕获Throwable...)
  • 如果你从 try 块内部返回会发生什么?
  • 如果 catch 块抛出异常会发生什么?

一个finally块确保但是您退出该块(以几种显式中止整个过程的方式为模),它将被执行。这对于确定性的资源清理非常重要。

  • What happens if an exception you're not handling gets thrown? (I hope you're not catching Throwable...)
  • What happens if you return from inside the try block?
  • What happens if the catch block throws an exception?

A finally block makes sure that however you exit that block (modulo a few ways of aborting the whole process explicitly), it will get executed. That's important for deterministic cleanup of resources.

旧城烟雨 2024-09-19 23:57:57

请注意(至少在 Java 中,也可能在 C# 中)也可以有一个没有 catchtry 块,但有一个 finally 。当 try 块中发生异常时,finally 块中的代码将在异常向上抛出之前运行:

InputStream in = new FileInputStream("somefile.xyz");
try {
    somethingThatMightThrowAnException();
}
finally {
    // cleanup here
    in.close();
}

Note that (in Java at least, probably also in C#) it's also possible to have a try block without a catch, but with a finally. When an exception happens in the try block, the code in the finally block is run before the exception is thrown higher up:

InputStream in = new FileInputStream("somefile.xyz");
try {
    somethingThatMightThrowAnException();
}
finally {
    // cleanup here
    in.close();
}
梨涡少年 2024-09-19 23:57:57

您可能想要放置您想要执行的代码,无论 try 或 catch 块中发生什么情况。

另外,如果您正在使用多个 catch 并且您想放置一些对于所有 catch 块通用的代码,那么这将是一个放置的地方 - 但您无法确定 try 中的整个代码都已被执行。

例如:

conn c1 = new connection();
try {
    c1.dosomething();
} catch (ExceptionA exa) {
    handleexA();
    //c1.close();
} catch (ExceptionB exb) {
    handleexB();
    //c1.close();
} finally {
    c1.close();
}

You may want to put the code that you want to anyway get executed irrespective of what happens in your try or catch block.

Also if you are using multiple catch and if you want to put some code which is common for all the catch blocks this would be a place to put- but you cannot be sure that the entire code in try has been executed.

For example:

conn c1 = new connection();
try {
    c1.dosomething();
} catch (ExceptionA exa) {
    handleexA();
    //c1.close();
} catch (ExceptionB exb) {
    handleexB();
    //c1.close();
} finally {
    c1.close();
}
如歌彻婉言 2024-09-19 23:57:57

最后总是会被执行,而 catch 之后的代码可能不会被执行。

Finally always gets executed, where as your code after the catch may not.

活泼老夫 2024-09-19 23:57:57

还在向下滚动吗?干得好!

这个问题让我一度很难过。

try
{
 int a=1;
 int b=0;
 int c=a/b;
}
catch(Exception ex)
{
 console.writeline(ex.Message);
}
finally
{
 console.writeline("Finally block");
}
console.writeline("After finally");

在上述场景中会打印什么?
是的,猜对了:

  • ex.Message--无论它是什么(可能尝试除以零)

  • 最终阻止

  • finally 之后

    <前><代码>尝试
    {
    整数a=1;
    整数b=0;
    int c=a/b;
    }
    捕获(异常前)
    {
    抛出(前);
    }
    最后
    {
    console.writeline("终于阻塞了");
    }
    console.writeline("最后之后");

这会打印什么?没有什么!由于 catch 块引发了错误,因此它会引发错误。

在良好的编程结构中,您的异常将被集中,从某种意义上说,该代码将从另一层处理。为了刺激这种情况,我将嵌套尝试此代码。

try
{    
 try
    {
     int a=1;
     int b=0;
     int c=a/b;
    }
    catch(Exception ex)
    {
     throw(ex);
    }
    finally
    {
     console.writeline("Finally block")
    }
    console.writeline("After finally");
}
catch(Exception ex)
{
 console.writeline(ex.Message);
}

在这种情况下,输出将是:

  • Finally block
  • ex.Message——无论它是什么。

很明显,当您捕获异常并将其再次扔到其他层(漏斗)时,抛出后的代码不会被执行。它的作用类似于函数内的 return 的工作方式。

您现在知道为什么不在 catch 块之后的代码上关闭资源。将它们放在 finally 块中。

Still scrolling down? Here you go!

This question gave me tough time back a while.

try
{
 int a=1;
 int b=0;
 int c=a/b;
}
catch(Exception ex)
{
 console.writeline(ex.Message);
}
finally
{
 console.writeline("Finally block");
}
console.writeline("After finally");

what would be printed in the above scenario?
Yes guessed it right:

  • ex.Message--whatever it is (probably attempted division by zero)

  • Finally block

  • After finally

    try
    {
        int a=1;
        int b=0;
        int c=a/b;
    }
    catch(Exception ex)
    {
        throw(ex);
    }
    finally
    {
        console.writeline("Finally block");
    }
    console.writeline("After finally");
    

What would this print? Nothing! It throws an error since the catch block raised an error.

In a good programming structure, your exceptions would be funneled, in the sense that this code will be handled from another layer. To stimulate such a case i'll nested try this code.

try
{    
 try
    {
     int a=1;
     int b=0;
     int c=a/b;
    }
    catch(Exception ex)
    {
     throw(ex);
    }
    finally
    {
     console.writeline("Finally block")
    }
    console.writeline("After finally");
}
catch(Exception ex)
{
 console.writeline(ex.Message);
}

In this case the output would be:

  • Finally block
  • ex.Message--whatever it is.

It is clear that when you catch an exception and throw it again into other layers(Funneling), the code after throw does not get executed. It acts similar to just how a return inside a function works.

You now know why not to close your resources on codes after the catch block.Place them in finally block.

子栖 2024-09-19 23:57:57

即使我们的应用程序被强制关闭,仍然会有一些我们必须执行的任务(例如内存释放、关闭数据库、释放锁等),如果您在 finally 中编写这些代码行,则会阻止它无论是否抛出异常都会执行...

您的应用程序可能是线程的集合,Exception终止线程但不是整个应用程序,在这种情况下finally是更有用。

在某些情况下,finally不会执行,例如 JVM 失败、线程终止等。

Even though our application is closed forcefully there will be some tasks, which we must execute (like memory release, closing database, release lock, etc), if you write these lines of code in the finally block it will execute whether an exception is thrown or not...

Your application may be a collection of threads, Exception terminates the thread but not the whole application, in this case finally is more useful.

In some cases finally won't execute such as JVM Fail, Thread terminate, etc.

大姐,你呐 2024-09-19 23:57:57

因为无论可能抛出任何异常,您都需要执行该代码。例如,您可能需要清理一些非托管资源(“using”构造编译为 try/finally 块)。

Because you need that code to execute regardless of any exceptions that may be thrown. For example, you may need to clean up some unmanaged resource (the 'using' construct compiles to a try/finally block).

苏辞 2024-09-19 23:57:57

有时您可能无论如何都想执行一段代码。是否抛出异常。然后使用finally

There may be times when you want to execute a piece of code no matter what. Whether an exception is thrown or not. Then one uses finally.

雪落纷纷 2024-09-19 23:57:57

finally 总是执行,除非 JVM 被关闭,finally 只是提供了一种将清理代码放在一个地方的方法。

如果您必须将清理代码放入每个 catch 块中,那就太乏味了。

finally ALWAYS executes, unless the JVM was shut down, finally just provides a method to put the cleanup code in one place.

It would be too tedious if you had to put the clean up code in each of the catch blocks.

×纯※雪 2024-09-19 23:57:57

如果catch块抛出任何异常,那么剩余的代码将不会执行,因此我们必须编写finaly块。

If catch block throws any exception then remaining code will not executed hence we have to write finaly block.

以酷 2024-09-19 23:57:57

java中的finally块可用于放置“清理”代码,例如关闭文件,关闭连接等。


如果程序退出(通过调用System.exit()或导致致命错误,则finally块将不会被执行)中止进程)。

finally block in java can be used to put "cleanup" code such as closing a file, closing connection etc.


The finally block will not be executed if program exits(either by calling System.exit() or by causing a fatal error that causes the process to abort).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文