在try语句块中申请了资源,在离开try语句块之前要释放掉资源,但是如果在这中间出现异常,就会跳转到catch语句块中执行异常处理程序,try语句块中的资源无法释放,造成内存泄漏。在java中,finally关键字有效的解决了这个问题。
在try catch finally语句中,finally是一定会被执行的。利用这个特性可以在finally语句中释放资源。
当try语句块中没有出现异常时,执行完try语句块中的程序,执行finally语句块中的程序。当try语句块中出现异常时,跳转到catch语句块中执行异常处理程序,然后执行finally语句块中的程序。
(一)当try语句块或者catch语句块的最后有return语句时,return语句和finally语句块的执行顺序是交叉的。
return 表达式;或 return 函数;
执行顺序:
(1)计算return语句中表达式的值,或者执行return语句中的函数调用并求出函数的返回值。
(2)执行finally语句块
(3)return语句返回
package com;
public class Finally {
public static void main(String[] args) {
System.out.println("main");
System.out.println(func1());
}
public static String func1() {
System.out.println("func1");
try {
System.out.println("try");
return func2();
} catch (Exception e) {
System.out.println("catch");
return "return error";
}
finally {
System.out.println("finally block");
}
}
public static String func2() {
System.out.println("func2");
return func3();
}
public static String func3() {
System.out.println("func3");
return func4();
}
public static String func4() {
System.out.println("func4");
return func5();
}
public static String func5() {
System.out.println("func5");
return "return func5";
}
}
执行结果:
main
func1
try
func2
func3
func4
func5
finally block
return func5
如果try语句块中出现异常,执行顺序也是一样的。
package com;
public class Finally {
public static void main(String[] args) {
System.out.println("main");
System.out.println(func1());
}
public static String func1() {
System.out.println("func1");
try {
System.out.println("try");
Exception e = new Exception();
throw e;
} catch (Exception e) {
System.out.println("catch");
return func2();
}
finally {
System.out.println("finally block");
}
}
public static String func2() {
System.out.println("func2");
return func3();
}
public static String func3() {
System.out.println("func3");
return func4();
}
public static String func4() {
System.out.println("func4");
return func5();
}
public static String func5() {
System.out.println("func5");
return "return func5";
}
}
执行结果:
main
func1
try
catch
func2
func3
func4
func5
finally block
return func5
(二)当try语句块或者catch语句块的最后有System.exit(0);语句时,finally语句块将不再执行。
如果try语句块中没有出现异常。
package com;
public class Finally {
public static void main(String[] args) {
System.out.println("main");
func1();
}
public static void func1() {
try {
System.out.println("try");
System.exit(0);
} catch (Exception e) {
System.out.println("catch");
}
finally {
System.out.println("finally block");
}
}
}
执行结果:
main
try
如果try语句块中出现异常。
package com;
public class Finally {
public static void main(String[] args) {
System.out.println("main");
func1();
}
public static void func1() {
try {
System.out.println("try");
Exception e = new Exception();
throw e;
} catch (Exception e) {
System.out.println("catch");
System.exit(0);
}
finally {
System.out.println("finally block");
}
}
}
执行结果:
main
try
catch