java try、catch 和 finally 的确切执行顺序是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17874190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
what is the exact order of execution for try, catch and finally?
提问by user13267
In this java code,
在这个java代码中,
import java.io.IOException;
public class Copy
{
public static void main(String[] args)
{
if (args.length != 2)
{
System.err.println("usage: java Copy srcFile dstFile");
return;
}
int fileHandleSrc = 0;
int fileHandleDst = 1;
try
{
fileHandleSrc = open(args[0]);
fileHandleDst = create(args[1]);
copy(fileHandleSrc, fileHandleDst);
}
catch (IOException ioe)
{
System.err.println("I/O error: " + ioe.getMessage());
return;
}
finally
{
close(fileHandleSrc);
close(fileHandleDst);
}
}
static int open(String filename)
{
return 1; // Assume that filename is mapped to integer.
}
static int create(String filename)
{
return 2; // Assume that filename is mapped to integer.
}
static void close(int fileHandle)
{
System.out.println("closing file: " + fileHandle);
}
static void copy(int fileHandleSrc, int fileHandleDst) throws IOException
{
System.out.println("copying file " + fileHandleSrc + " to file " +
fileHandleDst);
if (Math.random() < 0.5)
throw new IOException("unable to copy file");
System.out.println("After exception");
}
}
the output that I expect is
我期望的输出是
copying file 1 to file 2
I/O error: unable to copy file
closing file: 1
closing file: 2
However sometimes I get this expected output and at other times I get the following output:
但是有时我会得到这个预期的输出,而有时我会得到以下输出:
copying file 1 to file 2
closing file: 1
closing file: 2
I/O error: unable to copy file
and sometimes even this output:
有时甚至是这个输出:
I/O error: unable to copy file
copying file 1 to file 2
closing file: 1
closing file: 2
and whether I get the first, second or third output seems to happen randomly during every execution. I found THIS POSTthat apparently talks about the same problem, but I still don't understand why I sometimes get output 1, 2 or 3. If I understand this code correctly then output 1 should be what I get every time (the exception occurs). How do I ensure that I get output 1 consistently, or be able to tell when I will be getting output 1 or when I will be getting output 2 or 3?
以及我是否获得第一个、第二个或第三个输出似乎在每次执行期间随机发生。我发现这个帖子显然讨论了同样的问题,但我仍然不明白为什么我有时会得到输出 1、2 或 3。如果我正确理解了这段代码,那么输出 1 应该是我每次得到的结果(发生异常)。我如何确保始终获得输出 1,或者能够判断何时获得输出 1 或何时获得输出 2 或 3?
回答by Ted Hopp
The issue is that you are writing some output to System.out
and some to System.err
. These are independent streams, with independent buffering. The timing of when they are flushed is, as far as I know, not specified.
问题是,你正在写一些输出System.out
和一些人System.err
。这些是独立的流,具有独立的缓冲。据我所知,它们被刷新的时间没有指定。
The short of it is that when writing to different streams, you cannot use the order in which the output shows up to determine the order in which the calls to println()
occurred. Note that the output to System.out
always appears in the expected order.
简而言之,当写入不同的流时,您不能使用输出显示的顺序来确定调用println()
发生的顺序。请注意,输出 toSystem.out
始终以预期的顺序出现。
As far as order of execution, the body of the try
is executed first. If it throws an exception, the body of the appropriate catch
clause is then executed. The finally
block is always executed last.
就执行顺序而言,首先执行的主体try
。如果它抛出异常,catch
则执行相应子句的主体。该finally
块总是最后执行。
回答by Ruchira Gayan Ranaweera
First execute Try
block if it is success finally will execute, if try
block fail then catch
will execute and finally
execute. What ever happen finally block will execute.
先执行Try
块,如果成功最后执行,如果try
块失败则catch
执行并finally
执行。finally 块中发生的任何事情都会执行。
But
但
If you call System.exit(0)
finally block not executed
如果调用System.exit(0)
finally 块未执行
回答by Maclane
The thing with exception handling using try catch block is that the control will go inside try if any exception it will get inside catch block. But the control will go to final block every time it executs.
使用 try catch 块进行异常处理的事情是,如果任何异常将进入 catch 块,则控件将进入 try 内部。但是每次执行时,控件都会转到最后一个块。
回答by Curt
You are writing your error message to both stdout and stderr. They have different buffers, so there is no guarantee that the output you see will be in the same order as you created it, between the two output streams.
您正在将错误消息写入 stdout 和 stderr。它们具有不同的缓冲区,因此无法保证在两个输出流之间看到的输出与您创建的输出顺序相同。
Since I can see no errors in your code (although the superfluous return;
in your catch
segment stuck in my craw a little bit), let me suggest that you write all of your messages to stderr, and see if the message order is a little more in line with what you were expecting.
由于我看不出你的代码中有任何错误(尽管return;
你的catch
段中的多余部分有点卡在我的爪子里),让我建议你将所有消息写入 stderr,并查看消息顺序是否更符合与您的期望。
回答by Matthias
You have one glitch in your example which I would remove. You are writing to both System.out and System.err and expection your console to synchronize both streams correctly. To remove side effects I would just use one stream here.
你的例子中有一个小故障,我会删除它。您正在写入 System.out 和 System.err 并期望您的控制台正确同步两个流。为了消除副作用,我在这里只使用一个流。