黑马程序员技术交流社区
标题:
finally 语句块一定会执行吗?
[打印本页]
作者:
王海彬
时间:
2015-9-28 20:09
标题:
finally 语句块一定会执行吗?
下面的程序在寻常的Hello world 程序中添加了一段不寻常的曲折操作。那么,它将会打印出什么呢?
public class HelloGoodbye {
public static void main(String[] args) {
try {
System.out.println("Hello world");
System.exit(0);
} finally {
System.out.println("Goodbye world");
}
}
}
这个程序包含两个println语句:一个在try语句块中,另一个在相应的finally语句块中。try 语句块执行它的println 语句,并且通过调用System.exit 来提
前结束执行。在此时,你可能希望控制权会转交给finally 语句块。然而,如果你运行该程序,就会发现它永远不会说再见:它只打印了Hello world。
不论try语句块的执行是正常地还是意外地结束,finally语句块确实都会执行。
然而在这个程序中,try 语句块根本就没有结束其执行过程。System.exit 方法将停止当前线程和所有其他当场死亡的线程。finally 子句的出现并不能给予线
程继续去执行的特殊权限。
当System.exit 被调用时,虚拟机在关闭前要执行两项清理工作。首先,它执行所有的关闭挂钩操作,这些挂钩已经注册到了Runtime.addShutdownHook 上。这对于释放JVM 之外的资源将很有帮助。务必要为那些必须在JVM 退出之前发生的行为关闭挂钩。下面的程序版本示范了这种技术,它可以如我们所期望地打印出
Hello world 和Goodbye world:
public class HelloGoodbye1 {
public static void main(String[] args) {
System.out.println("Hello world");
Runtime.getRuntime().addShutdownHook(
new Thread() {
public void run() {
System.out.println("Goodbye world");
}
});
System.exit(0);
}
}
JVM 执行在System.exit 被调用时执行的第二个清理任务与终结器有关。如果System.runFinalizerOnExit 或它的魔鬼双胞胎Runtime.runFinalizersOnExit
被调用了,那么JVM 将在所有还未终结的对象上面调用终结器。这些方法很久以前就已经过时了,而且其原因也很合理。无论什么原因,永远不要调用System.runFinalizersOnExit和Runtime.runFinalizersOnExit:它们属于Java类库中最危险的方法之一[ThreadStop]。调用这些方法导致的结果是,终结器会在那些其他线程正在并发操作的对象上面运行,从而导致不确定的行为或导致死锁。
总之,System.exit 将立即停止所有的程序线程,它并不会使finally 语句块得到调用,但是它在停止VM 之前会执行关闭挂钩操作。当VM 被关闭时,请使用关闭挂钩来终止外部资源。通过调用System.halt 可以在不执行关闭挂钩的情况下停止JVM,但是这个方法很少使用。
作者:
xinchi
时间:
2015-9-28 20:12
很好,总结不错,点赞
作者:
王海彬
时间:
2015-9-28 20:18
老师也讲过,这个例子比较简单
作者:
iceknc
时间:
2015-9-28 21:32
不错不错,学习了
作者:
王海彬
时间:
2015-9-30 16:45
java中有些知识点很绕有些知识点很容易忽略,有些就是要理解才能更好的记忆
作者:
meijunwei6275
时间:
2015-9-30 17:21
不错,学习一下
作者:
王海彬
时间:
2015-10-3 16:33
感谢大家的发言,希望大家都能上就业办
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2