我很难理解这一点;
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) (使用另一个文件)。这按预期工作。
如果它有效,那么我有一个 block 文件名称列表,并且我进入另一个循环在每个 block 文件上运行 bar。如果某个栏失败,那么我会处理异常,清理内容,并继续循环使用下一个 block 文件。
但是,发生的情况是:它开始处理异常,同时用另一个文件启动另一个 foo。我可以得到这样的输出:
Starting foo with file7
Failed bar on file7.block3
Starting foo with file12
Java.lang.NullPointerException
....
因此 printStackTrace 发生在下一个 foo 启动之后。我不明白这一点。它应该继续执行 bar 函数的循环和 foo 的其余部分,然后返回主循环并启动另一个 foo。
有人能给我解释一下这种奇怪的行为吗?也许告诉我要改变什么,以便 catch 中的所有内容在另一个 foo 开始之前运行?
PS:我知道这不是“最小完整和可验证”,但其中有太多东西使其完整和可验证,而且它真的很难理解。我希望这里的内容足够了。
最佳答案
你的问题很难理解,而且代码显然不是真实的,但我认为你是在问为什么消息以意想不到的顺序显示。
一个可能的答案是:
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 流即可。
关于java - 程序在 catch block 结束之前继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52235167/