Finally使用时注意事项
finally的使用
通常情况下finally代码块会定义在try语句和catch语句之后,在方法结束前执行,且无论有没有异常finally语句都会执行。
1.finally示例
private void finalllyTest() {
try {
System.out.println("try代码块执行了");
throw new Exception();
} catch (Exception e) {
System.out.println("catch代码块执行了");
} finally {
System.out.println("finally代码块执行了");
}
}
try代码块执行了
catch代码块执行了
finally代码块执行了
2.删除catch的finally语句
private void finalllyTest() {
try {
System.out.println("try代码块执行了");
} finally {
System.out.println("finally代码块执行了");
}
}
try代码块执行了
finally代码块执行了
有无catch与finally的的执行无关
3.finally的使用场景
finally代码块多数情况下都会执行,一般在其中执行一些数据库关闭、文件流关闭、释放线程等操作。
4.finally的执行机制
没有异常
try {
System.out.println("try执行了");
} finally {
System.out.println("finally执行了");
}
try执行了
finally执行了
有异常无处理器
try {
System.out.println("try执行了");
throw new Exception();
} finally {
System.out.println("finally执行了");
}
有异常无异常处理器的代码块会报错
有异常处理器
private void finallyTest() {
try {
System.out.println("try执行了");
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
} finally {
System.out.println("finally执行了");
}
}
try代码块有返回值
/**
* @author 张阔
*/
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.finallyTest();
}
private Object finallyTest() {
try {
System.out.println("try执行了");
return "nothing";
} catch (Exception e) {
System.out.println("catch执行了");
} finally {
System.out.println("finally执行了");
}
return "everything";
}
}
try语句中有返回值不影响finally正常执行
catch中有返回值
/**
* @author 张阔
*/
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.finallyTest();
}
private Object finallyTest() {
try {
System.out.println("try执行了");
throw new Exception();
} catch (Exception e) {
System.out.println("catch执行了");
return "nothing";
} finally {
System.out.println("finally执行了");
}
}
}
catch语句中有返回值不影响finally的正常运行
5.finally不执行的场景
虽然通常情况下finally都是执行的,但在个别情况下会跳过fianlly语句结束方法
调用System.exit()函数
/**
* @author 张阔
*/
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.finallyTest(1);
//t.finallyTest(0);
}
private void finallyTest(int n) {
try {
if (n == 1) {
System.out.println("try执行了");
throw new Exception();
}
System.exit(0);
} catch (Exception e) {
System.out.println("catch执行了");
System.exit(0);
} finally {
System.out.println("finally执行了");
}
}
}
当n=1时
当n=0时
无论System.exit(0);语句在try代码块还是catch代码块中被执行,都越过finally结束了
注:
Sytstem.exit();
实际上调用了Runtime的方法,执行时可以等同于Runtime.getRuntime().exit();
用来终止当前运行的虚拟机
调用halt函数
/**
* @author 张阔
*/
public class Test {
public static void main(String[] args) {
Test t = new Test();
}
private void finallyTest(int n) {
try {
System.out.println("try执行了");
Runtime.getRuntime().halt(0);
throw new Exception();
} catch (Exception e) {
System.out.println("catch执行了");
} finally {
System.out.println("finally执行了");
}
}
}
halt()方法与exit()作用相似,但有所不同,halt会强制停止当前运行的JAVA虚拟机,不会等待任何相关线程完成工作,此方法永远不能正常返回。
守护进程(暂时不理解=。=)
import java.util.concurrent.TimeUnit;
/**
* Finally shoud be always run ?
*/
public class DaemonsDontRunFinally {
public static void main(String[] args) {
Thread t = new Thread(new ADaemon());
t.setDaemon(true);
t.start();
}
}
class ADaemon implements Runnable {
public void run() {
try {
System.out.println("start ADaemon...");
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("Exiting via InterruptedException");
} finally {
System.out.println("This shoud be always run ?");
}
}
}
如果守护进程刚开始执行到finally代码块,此时没有任何其他非守护线程,那么虚拟机将退出,此时JVM不会等待守护线程的finally代码块执行完成。
try无限循环
/**
* @author 张阔
*/
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.finallyTest();
}
private int finallyTest() {
try {
while (true) {
}
} catch (Exception e) {
System.out.println("catch执行了");
} finally {
System.out.println("finally执行了");
}
return 10;
}
}
finally:两眼一闭,这辈子运行不到我了。