我很难理解这一点;
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:我知道这不是“最低限度的完整性和可验证性”,但是其中有太多的内容无法使其完整且可验证,这真的很难理解。我希望这里足够了。
答案 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