- public class Test
- {
- public static void main(String[] args)
- {
- try
- {
- System.out.println("Hello" );
- return ;
- }finally
- {
- System.out.println("Goodbye" );
- }
- }
- }
public class Test
{
public static void main(String[] args)
{
try
{
System.out.println("Hello");
return;
}finally
{
System.out.println("Goodbye");
}
}
}
输出结果为:
Hello
Goodbye
- public class Test
- {
- public static void main(String[] args)
- {
- try
- {
- System.out.println("Hello" );
- System.exit(0 );
- }finally
- {
- System.out.println("Goodbye" );
- }
- }
- }
public class Test
{
public static void main(String[] args)
{
try
{
System.out.println("Hello");
System.exit(0);
}finally
{
System.out.println("Goodbye");
}
}
}
输出结果为:
Hello
2、try {} 里有一个 return 语句,那么紧跟在这个 try 后的 finally {} 里的 code 会不会被执行,什么时候被执行,在 return 前还是后 ?
- public class test {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- System.out.println(new test().test());;
- }
- static int test()
- {
- int x = 1 ;
- try
- {
- return x;
- }
- finally
- {
- ++x;
- System.out.println(x);
- System.out.println("aaa" );
- }
- }
- }
运行结果是
2
aaa
1
为什么呢?主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。
public class smallT
{
public static void main(String args[])
{
smallT t = new smallT();
int b = t.get();
System.out.println(b);
}
public int get()
{
try
{
return 1 ;
}
finally
{
return 2 ;
}
}
}
返回的结果是 2 。
我可以通过下面一个例子程序来帮助我解释这个答案,从下面例子的运行结果中可以发现, try 中的 return 语句调用的函数先于 finally 中调用的函数执行,也就是说 return 语句先执行, finally 语句后执行,所以,返回的结果是 2 。 Return 并不是让函数马上返回,而是 return 语句执行后,将把返回结果放置进函数栈中,此时函数并不是马上返回,它要执行 finally 语句后才真正开始返回。
在讲解答案时可以用下面的程序来帮助分析:
public class Test {
/**
* @param args add by zxx ,Dec 9, 2008
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System . out .println( new Test().test());;
}
int test()
{
try
{
return func1();
}
finally
{
return func2();
}
}
int func1()
{
System . out .println( "func1" );
return 1;
}
int func2()
{
System . out .println( "func2" );
return 2;
}
}
----------- 执行结果 -----------------
func1
func2
2
结论: finally 中的代码比 return 和 break 语句后执行
3、finally中在return时:
public class Test {
public static void main(String[] args) {
System.out.println(decision());
}
static boolean decision() {
try {
return true;
} finally {
return false;
}
}
}
你可能会认为这个程序是不合法的。毕竟,decision方法不能同时返回true和false。如果你尝试一下,就会发现它编译时没有任何错误,并且它所打印的是false。为什么呢?
原因就是在一个try-finally语句中,finally语句块总是在控制权离开try语句块时执行的。无论try语句块是正常结束的,还是意外结束 的,情况都是如此。一条语句或一个语句块在它抛出了一个异常,或者对某个封闭型语句执行了一个break或continue,或是象这个程序一样在方法中 执行了一个return时,将发生意外结束。它们之所以被称为意外结束,是因为它们阻止程序去按顺序执行下面的语句。
当try语句块和finally语句块都意外结束时,在try语句块中引发意外结束的原因将被丢弃,而整个try-finally语句意外结束的原 因将于finally语句块意外结束的原因相同。在这个程序中,在try语句块中的return语句所引发的意外结束将被丢弃,而try-finally 语句意外结束是由finally语句块中的return造成的。简单地讲,程序尝试着(try)返回(return)true,但是它最终 (finally)返回(return)的是false。
丢弃意外结束的原因几乎永远都不是你想要的行为,因为意外结束的最初原因可能对程序的行为来说会显得更重要。对于那些在try语句块中执行 break、continue或return语句,只是为了使其行为被finally语句块所否决掉的程序,要理解其行为是特别困难的。
总之,每一个finally语句块都应该正常结束,除非抛出的是不受检查的异常。千万不要用一个return、break、continue或throw来退出一个finally语句块,并且千万不要允许将一个受检查的异常传播到一个finally语句块之外去。