在Java中,是“最后”。 保证调用块(在主方法中)?

发布于 2024-07-13 23:30:10 字数 1063 浏览 5 评论 0原文

我是一个Java菜鸟,我想知道,如果我有以下典型的Java代码,

public class MyApp {
  public static void main(String[] args) {
    try {
      // do stuff
    } catch {
      // handle errors
    } finally {
      // clean up connections etc.
    }
  }
}

JVM是否保证finally块将始终运行? 为了理解我的出发点,我习惯了 C/C++ 程序,如果您取消引用 NULL 指针,并且之后无法运行任何代码,这些程序可能会崩溃。

但据我了解 Java 和整个 GC/托管内存业务,不存在空指针取消引用之类的东西,一切都是可捕获的期望,因此我的程序实际上没有办法崩溃,可以使其跳过finally ,或者有吗? 例如,在 Python 中,我通常会这样做

try:
  # do stuff
except AnExceptionIKnewMightHappen:
  # react in an appropriate way
except:
  # log that weird error I had not known could happen

,而且从来没有任何应用程序在不通过我的代码的情况下死掉。

当然,如果操作系统由于某种原因杀死了进程(或者如果某些东西杀死了整个系统,比如拔掉插头),那么 Java 就无能为力了。 另外,从 PHP 中我知道你无法防止不可捕获的错误,即使解释器在错误发生后仍然存在(至少它能够输出正确的消息)。

编辑:为了清楚起见(没有被任何人真正误解),让我补充一下,我正在寻找在我的代码中可能导致最终被绕过的东西。 因此,指向 System.exit 是一个有用的提醒,尽管我不明白为什么我想做那样的事情。

JVM 退出是一种相当明显的方式,我将其视为外部原因。 指出您还必须记住 JVM 和应用程序保持运行时线程退出的可能性的注释非常有帮助,因为尽管现在对我来说似乎很明显,但我没有想到这一点。

I'm a Java rookie and I was wondering, if I have the following typical Java code

public class MyApp {
  public static void main(String[] args) {
    try {
      // do stuff
    } catch {
      // handle errors
    } finally {
      // clean up connections etc.
    }
  }
}

does the JVM guarantee that the finally block will always be run? To understand where I'm coming from, I'm used to C/C++ programs that might just crash if you dereference a NULL pointer and you can't have any code to be run after that.

But as I understand Java and the whole GC / managed memory business in general, there's no such thing as a null pointer dereferencing, everything is a catchable expection, so there's not really a way for my program to crash that could make it skip the finally, or is there? For example, in Python, I usually do

try:
  # do stuff
except AnExceptionIKnewMightHappen:
  # react in an appropriate way
except:
  # log that weird error I had not known could happen

and I have never had any app die without passing through my code.

Of course, if the OS for some reason kills the process (or if something kills the whole system, like pulling the plug) there's not much Java can do. Also, from PHP I know non-catchable errors that you can't protect against, even though the interpreter was still there after it happened (at least it is able to output a proper message).

Edit: Just for clarity (it wasn't really misunderstood by anyone), let me add that I was looking for things inside my code that could lead to the finally being bypassed. So pointing to System.exit was a helpful reminder, even though I can't see why I would want to do something like that.

The JVM exiting is a rather obvious way and I'd count that as an external cause. The note pointing out that you also have to remember the possibilty of threads exiting while the JVM and the app keep running was very helpful, because even though it also seems obvious to me now, I hadn't thought of it.

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

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

发布评论

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

评论(10

一萌ing 2024-07-20 23:30:10

基本上是的,除了这里列出的注释此处(强调我的) :

如果在执行 try 或 catch 代码时 JVM 退出,
那么finally 块可能不会执行。 同样,如果线程
执行try或catch代码被中断或杀死,finally
即使应用程序作为一个整体,块可能不会执行
继续。

Basically yes, except for the note listed here (emphasis mine):

If the JVM exits while the try or catch code is being executed,
then the finally block may not execute. Likewise, if the thread
executing the try or catch code is interrupted or killed, the finally
block may not execute even though the application as a whole
continues.

诗酒趁年少 2024-07-20 23:30:10

不保证:

public class Main {
    public static void main(String args[]) {
        try {
            System.out.println("try");
            System.exit(0);
        } catch (Exception e) {
            System.out.println("exception");
        } finally {
            System.out.println("finally");
        }
    }
}

运行它。

It is not guaranteed:

public class Main {
    public static void main(String args[]) {
        try {
            System.out.println("try");
            System.exit(0);
        } catch (Exception e) {
            System.out.println("exception");
        } finally {
            System.out.println("finally");
        }
    }
}

Run that.

幻想少年梦 2024-07-20 23:30:10

总之,是的。

Java 中finally 块中的代码始终执行,除非:

  • JVM 在 try 或 catch 块期间退出
  • 运行代码的线程在 try 或 catch 块期间被中断或终止

(来自: http://java.sun.com/docs/books/tutorial/essential/exceptions/finally.html

所以,除非你显式调用System.exit(int),或者从外部杀死进程或线程,否则你可以依赖它。

In a word, yes.

Code in the finally block in Java always executes unless:

  • The JVM exits during the try or catch block
  • The thread running the code is interrupted or killed during the try or catch block

(from: http://java.sun.com/docs/books/tutorial/essential/exceptions/finally.html)

So, unless you explicitly call System.exit(int), or kill the process or thread externally, you can rely on it.

时光无声 2024-07-20 23:30:10

当然,finally 块每次都会运行。 除非 JVM 崩溃或调用 exit() 函数。 我的代码中,Java 应用程序调用了出现段错误的 JNI 本机代码。 由此产生的崩溃杀死了 JVM,并阻止了finally 的运行。

Absolutely, that finally block will run, every time. Except in the case of a JVM crash or the exit() function being called. I have had code where the Java application made calls out to JNI native code which segfaulted. The resulting crash killed the JVM, and prevented the finally from running.

剧终人散尽 2024-07-20 23:30:10

克里斯·卡梅伦是对的。 但通常会执行finally块。 Java 中确实存在空指针解除引用:

try {
    List<Object> x = null;
    x.get(1); //throws the unchecked NullPointerException
} finally {
    //will be executed
}

finally 块被执行。

Chris Cameron is correct. But normally a finally-block gets executed. Null pointer dereferece does exist in Java:

try {
    List<Object> x = null;
    x.get(1); //throws the unchecked NullPointerException
} finally {
    //will be executed
}

The finally-Block gets executed.

感受沵的脚步 2024-07-20 23:30:10

是的,JVM 总是执行它。 有保证。

当然...如果 JVM 本身死亡(例如:System.exit()),那么它就无法保证任何事情。 但 JVM 的消亡并不是 Java 内部的问题。

Yes, the JVM always executes it. Gaurranteed.

Of course ... if the JVM itself dies (eg: System.exit()), then it's not in a position to gaurrantee anything. But the JVM dying is not a within-java issue.

无需解释 2024-07-20 23:30:10

嗯,是的:) 无论您的代码是否输入 catch,finally 都会运行。 这是放置尝试后清理的代码的好地方。

显然,如果你破坏了jvm,它就不会运行:)

Erm, yep :) Whether your code enters a catch or not, the finally will run. It's a good place to put code that cleans up after the try.

Obviously it won't run if you break the jvm :)

等风来 2024-07-20 23:30:10

是的,finally 块将始终运行,除非 JVM 崩溃(非常罕见,但这种情况可能会发生)。

Yes, the finally block will always be run, unless there is a crash of the JVM (very rare, but that can happen).

下雨或天晴 2024-07-20 23:30:10

唯一的例外是finally块没有被执行,要么是JVM崩溃,要么是system.exit()。

the only exceptions finally block is not executed are, either JVM crashes, or system.exit().

七度光 2024-07-20 23:30:10

很明显,JVM 退出后不会再运行,或者会在被杀死的线程中运行代码。 明显的。 因此,当 JVM 运行时,每个将要运行的代码都会运行,而在 JVM 退出或在死线程内后,什么都不会运行,甚至是任何类型的代码。 所以,没有办法阻止,但是如果需要finally子句,就放上它。

It seems pretty obvious that nothing more will run after JVM quit, or will run code in that killed thread. Obvious. So, when the JVM is running, every code that will run, will run, and after a JVM quit or inside a dead thread , nothing will run, even any kind of code. So, there is no way to prevent, but if there is a need to the finally clause, put it.

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