程序在catch块结束之前继续执行

时间:2018-09-08 12:05:34

标签: java try-catch

我很难理解这一点;

public static void main(String[] args){
    int nulberOfTests = 10;
    for( int i=0 ; i < numberOfTest ; i++){
        try{
            File file = getRandomFile(directory);
            foo(file);
        }catch(IOException){
            System.out.println("Failed to split the file: " + file.getName());
        }
    }
}

foo(File file) throws IOException{
    System.out.println("Starting foo with " +file.getName());
    List<String> blockFiles = split(file);  //this throws IOException.
    for(int i =0 ; i< blockFiles.size(); i++){
        try{
            bar(blockFiles.get(i)); //this throws some exceptions
        }catch (Exception e){
            System.err.println("Failed bar on " + blockFiles.get(i));
            e.printStackTrace();
            //Handle the exception
        }finally{
            //clean up
        }
    }
//continue with the function
}

在我看来是这样的:我启动了一个foo;它尝试分割文件;如果失败,则抛出IOException,然后我将其写入并继续执行另一个foo(file)(另一个文件)。这正在按预期方式工作。

如果有效,那么我有一个blockFiles名称列表,我进入另一个循环在每个blockFiles上运行。如果一个酒吧失败了,那么我会处理异常,清理东西,然后继续下一个blockfile的循环。

但是,发生的事情是:它开始处理该异常,同时,用另一个文件启动另一个foo。我可以有这样的输出:

Starting foo with file7
Failed bar on file7.block3
Starting foo with file12
Java.lang.NullPointerException
....

因此,printStackTrace在下一次foo启动之后发生。我不明白这一点。在返回主循环并启动另一个foo之前,它应该继续执行bar函数的循环以及foo的其余部分。

有人可以向我解释这种奇怪的行为吗?也许告诉我要进行哪些更改,以便使catch中的所有内容在另一个foo开始之前运行?

PS:我知道这不是“最低限度的完整性和可验证性”,但是其中有太多的内容无法使其完整且可验证,这真的很难理解。我希望这里足够了。

2 个答案:

答案 0 :(得分:2)

您的问题很难理解,代码显然不是真实的,但是我想您是在问为什么消息以意外的顺序显示。

一个可能的答案是:

System.out.println("Failed to split the file: " + file.getName());
System.out.println("Starting foo with " +file.getName());
System.err.println("Failed bar on " + blockFiles.get(i));
e.printStackTrace();

您是否注意到其中有些打印到System.out,而其他打印到System.err

这是两个不同的流。即使将它们重定向到同一位置,在Java中,两个流也将分别缓冲并具有不同的“自动刷新”特性。这意味着输出易于以意想不到的方式散布。例如:

public static void (String[] args) {
     System.out.println("Hi");
     System.err.println("Mom");
}

可能输出:

Hi
Mom

Mom
Hi

如果您需要按照代码编写错误消息或堆栈跟踪的顺序显示它们,只需对消息使用ONE流即可。

答案 1 :(得分:0)

接受的答案不正确或至少模棱两可。

如果将System.err替换为System.out,则两个println的顺序将相同:错误,然后是新文件的开始。

混乱的是堆栈跟踪。

原因是相同的。方法java.lang.Throwable.printStackTrace()写入System.err。

如果您希望获得期望的顺序,请在同一流中打印堆栈跟踪和消息。

要在System.out上打印堆栈跟踪,请使用:

SET_FIELD

java.lang.Throwable.printStackTrace()