13

我曾经认为当异常发生时,整个java应用程序都会被终止。例如,我编写了一个测试函数来测试我的想法。

public void test(){
    File fileDir=new File(sourceDataDir);
    if(fileDir.exists()){
        File[] files = fileDir.listFiles();
        for(int index=0 ; index<files.length ; index++){
            System.out.println("index = "+index);
            File file = files[index];
            if(index == 1)//delete a file to cause a FileNotFoundException
                file.delete();
            try {
                BufferedReader in = new BufferedReader(new FileReader(file));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
}

FileNotFoundException我手动删除了一个文件。我曾经认为当异常发生时整个应用程序将终止。但实际上,应用程序会继续读取剩余的文件。所以,我的问题是,在什么情况下异常会导致整个应用程序被终止?

4

6 回答 6

15

如果用 没有捕获catch到异常,则发生异常的线程将被终止。如果没有非守护线程保留,JVM 将终止。这是异常终止 JVM 的唯一方法。如果你捕捉到一个异常,它永远不会导致 JVM 终止。

于 2013-09-04T08:02:11.837 回答
15

我的问题是,在什么情况下,异常会导致整个应用程序终止?

它永远不会。只有 System.exit() 会导致整个程序终止(和 JVM 崩溃)

想想一个异常,就像一个break;可以突破方法的强大功能。中断可能导致循环退出,如果最后一个循环在唯一的非守护线程中,则程序将退出。但它不会导致它,即使它可能是你在程序死亡之前看到的最后一件事。

于 2013-09-04T07:32:50.203 回答
4

有两种主要类型的异常:

  • 不是运行时异常

它表明系统工作正常。您必须捕获异常,否则它将无法编译。它永远不会终止应用程序。如果你想终止,你必须在 catch 块中调用 System.exit(ERROR_NUMBER) 或抛出运行时异常。

  • 运行时异常

指示系统错误(例如,应用程序服务器配置错误)。你不必抓住它。如果您没有捕捉到它,它会终止应用程序,或者如果您编写 J2EE 应用程序,AS 可能会处理它并继续您的应用程序。

于 2013-09-04T07:41:39.933 回答
1

那么,我的问题是,在什么情况下,异常会导致整个应用程序被终止?

有关异常的详细信息,请参阅文档。至于您的问题 FileNotFoundException 是一个已检查的异常,这意味着您需要处理它。现在你必须选择

  1. 捕获 FileNotFoundException 并处理(您可以简单地打印堆栈跟踪并继续)
  2. 或者你可以把它扔给父母(调用方法)

在情况 1 中,您的 java 进程将一直持续到结束(假设没有发生运行时异常/错误)。

在情况 2 中,如果即使在父级(调用函数)中也没有捕获 FileNotFoundException 并且只是再次抛出它并继续这样做,则异常最终将落在 main() 方法中。如果你的 main() 方法抛出了这个异常,JVM 就会简单地关闭。

更新以澄清您的评论:

捕获异常与是否捕获异常无关。如果出现未缓存的异常,您仍然可以捕获它并让程序继续进行。但不建议这样做,因为根据未缓存异常的定义(根本不应该发生),如果发生未缓存异常,您不应该恢复。

考虑以下简单示例

public static void main(String args[]) {
    try {
        String s = null;
        System.out.println(s.length());
    } catch (Exception e) {
        System.out.println("Catch runtime exception but not quite sure what to do with it");
    }

    System.out.println("Reached here even after uncatched Exception");
}

输出是

Catch runtime exception but not quite sure what to do with it
Reached here even after uncatched Exception

因此,基本上每当发生异常时,如果您没有从源点的任何级别捕获它,它最终将传播到 main() 并且 JVM 最终将关闭。如果您确实捕获了它(无论捕获或未捕获的异常),您的程序将继续(在未捕获的异常的情况下输出可能与预期不同)并终止。

于 2013-09-04T07:52:03.843 回答
1

这是例外处理。它们有 2 种类型:CheckedUnchecked

Checked异常(不是 的子类的所有异常)RuntimeException必须在 a 中处理,try-catch否则代码将无法编译,就像FileNotFoundException. 正是由于这种强制处理,这些异常通常不会终止应用程序,除非它们一直被抛出到调用方法直到 main() 方法,在那里它们会停止它们发生的线程。

不需要处理异常(作为 的子类的所有异常),因为它们来自编程/数据缺陷(考虑除以零异常或尝试访问空对象的成员等)UncheckedRuntimeException这些通常会破坏应用程序并使它们出现的线程崩溃,这可能是您的单线程执行程序。

于 2021-09-04T20:14:43.073 回答
0

Exception handlersjava处理程序异常执行的次数

于 2013-09-04T07:41:12.927 回答