最近在学习简单的socket通信开发,在查找一些网上资料的时候,看到了之前在了解异常机制时没太注意的东西就是 finally关键字。
代码如下,中间部分省略
?
DataInputStream dis = null; DataOutputStream dos = null; try { cServerSocket = new ServerSocket(PORT); while (true) { System.out.println("正在等待客户连接..."); cSocket = cServerSocket.accept(); dis = new DataInputStream(cSocket.getInputStream()); dos = new DataOutputStream(cSocket.getOutputStream()); String clientStr = dis.readUTF(); dos.writeUTF("已收到信息:" + clientStr); /**省略部分代码,,**/ System.out.println("---------------------------------"); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (dis != null) { dis.close(); } if (dos != null) { dos.close(); } } catch (IOException e) { e.printStackTrace(); } }
?如果不使用finally关键字的时候,必须编写如何关闭流对象,且需要使close()方法在不论异常与否时都会执行,这就可以使用finally关键字了。
finally 块确保 close 方法总被执行,而不管 try 块内是否发出异常。因此,可以确保在退出该方法之前总会调用 close 方法。这样就可以确信close()方法已经执行并且没有泄漏资源。在此方法中不需要再有一个 catch 块。
finally 块必须与 try 或 try/catch 块配合使用。此外,不可能退出 try 块而不执行其 finally 块。如果 finally 块存在,则它总会执行。
/***********听说我是分割线***********/
以上是我对finally关键字在我的代码中的运用的了解,然而更进一步了解时。
发现一个使用finally关键字的问题,就是只有与 finally 相对应的 try 语句块得到执行的情况下,finally 语句块才会执行。如果是在 try 语句块之前返回(return)或者抛出异常,所以 try 对应的 finally 语句块没有执行。
例如:
?
package Test; public class Test { public static void main(String[] args) { System.out.println("return value of test(): " + test()); } public static int test() { int i = 1; System.out.println("the previous statement of try block"); i = i / 0; try { System.out.println("try block"); return i; }catch(Exception e){ e.printStackTrace(); return 0; } finally { System.out.println("finally block"); } } }
?这个道理好像是显而易见的,已经毕竟代码还没有执行到 try语句就已经出现异常时而停止执行了,即不会继续执行下面的代码。如果在try之前就return了一个值,效果也是一样的。
?
然而,,,,在我继续了解时发现,如果一个线程在执行 try 语句块或者 catch 语句块时被打断(interrupted)或者被终止(killed),与其相对应的 finally 语句块可能不会执行。。。
综上来看,如果try语句被正常的执行了,即被执行了且不会中断执行,这时finally语句一定会被执行。。。
?
然而发现 如果真的要深究finally块的执行顺序,还需要直接去了解Java语言规范更好,,先就到这,我还是去写安卓通信去了。。。
?
?
原文:http://flyingfairy.iteye.com/blog/2233861