最近在学习简单的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语言规范更好,,先就到这,我还是去写安卓通信去了。。。