finally
来源:互联网 发布:mac os sierra升级 编辑:程序博客网 时间:2024/05/21 22:52
一、使用finally避免内存泄漏
由于Java支持垃圾回收机制,为此,如果函数正常结束或异常而被迫退出,该函数所创建的所有对象会被自动回收,但是对于Socket或File资源必须要执行清理操作,以便资源回收。如果不对这些资源进行回收,那么就会出现内存泄漏。
public void reclaimResource() throws IOException{ ServerSocket server = new ServerSocket(5566); Socket socket = null; try{socket = server.accept();//业务代码..... }finally{if(null != socket) socket.close();//回收资源 if(null != server) server.close();//回收资源} }}
二、不要在finally块中处理返回值
public class FinallyTest {//把一个字符串转换为整数public static int getNumber(String str) throws NumberFormatException {try { int number = Integer.parseInt(str); return number; //1} catch (NumberFormatException ex) { throw ex; //2} finally { return -1; //3} }//测试客户端public static void main(String[] args) {try { int ret1 = getNumber("abc"); //4 int ret2 = getNumber("123"); //5 System.out.println("ret1=" + ret1 + ";ret2=" + ret2);} catch (Exception ex) { ex.printStackTrace();} }
答案揭晓: ret1=-1;ret2=-1
问题1:覆盖了try子句中的返回值
当执行代码2中的//4语句时,在getNumber函数中会产生一个NumberFormatException的异常,catch块在捕捉到该异常后直接抛出,之后的代码执行到了finally代码块,就会重置返回值为-1。
当执行代码2中的//5语句时,在getNumber函数中不会产生异常,会继续执行try代码块中的//1语句,但是此时函数并不会马上返回,之后的代码会执行到finally代码块,仍重置返回值为-1。
问题2:屏蔽了异常
当执行代码2中的//4语句时,明明抛出了异常,为什么在main函数中却捕捉不到了?
在异常代码块中,代码中加上try代码块就标志JVM运行到该语句时会有一个Throwable线程监视该方法运行,若出现异常,则交由异常逻辑处理,如代码2中就会登记当前的异常类型为NumberFormatException;接着执行器会执行finally代码块,会重新给方法运行状态赋值,按照如上finally的业务代码,也就是告诉调用者“该方法执行正确,没有产生异常,返回值为1”。于是,异常就这样消失了。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
思考:输出的值是什么?
public class FinallyTest { static class Color {private String name;public Color(String nm) { this.name = nm;}public String getName() { return this.name;}public void setName(String nm) { this.name = nm;} } public static Color getColor() {Color color = new Color("Red");try { return color;} catch (Exception ex) {} finally { color.setName("Black"); } return color; } // 测试客户端 public static void main(String[] args) {Color color = getColor();System.out.println(color.getName()); }}
答案是:Black
*因为前面提到try块并没有直接返回,而是执行了finally块中的语句,然后再返回。
1.按照我们程序员的惯性认知:当遇到return语句的时候,执行函数会立刻返回。但是,在Java语言中,如果存在finally就会有例外。除了return语句,try代码块中的break或continue语句也可能使控制权进入finally代码块。
2.请勿在try代码块中调用return、break或continue语句。万一无法避免,一定要确保finally的存在不会改变函数的返回值。
3.函数返回值有两种类型:值类型与对象引用。对于对象引用,要特别小心,如果在finally代码块中对函数返回的对象成员属性进行了修改,即使不在finally块中显式调用return语句,这个修改也会作用于返回值上。
2.请勿在try代码块中调用return、break或continue语句。万一无法避免,一定要确保finally的存在不会改变函数的返回值。
3.函数返回值有两种类型:值类型与对象引用。对于对象引用,要特别小心,如果在finally代码块中对函数返回的对象成员属性进行了修改,即使不在finally块中显式调用return语句,这个修改也会作用于返回值上。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
补充:不要在循环里写try/catch,要将循环写在try/catch块中。
在启用JIT编译器的情形下两种方式生成的bytecode是几乎相同的,执行时间并没有什么不同。但是一旦将JVM的JIT关闭后,两者的bytecode差异很大,第二种方式执行效率会更高些。
阅读全文
0 0
- Finally~~
- FINALLY
- Finally
- finally
- finally
- finally
- finally
- finally
- finally
- Finally Passed!!
- try finally
- tyr-finally
- finally (转)
- try-finally
- try---finally
- 关于finally
- finally analysis
- finally语句
- Android Studio添加依赖 导包报红
- CUDA学习笔记(4) CUDA计时函数
- MarkDown 编辑器学习
- C/C++ 第八周串和数组 (一)对称矩阵压缩存储的实现与应用 项目3—(2)
- java使用CsvReader和CsvWriter对csv文件内容进行读取和写入操作
- finally
- [找规律] SRM599 500-point FindPolygons
- PyQt5简单小工具制作步骤:
- ajax传输,后台同步,后台json传输,文件,文件夹复制删除,查询,新建,在线压缩
- 在gradle中使用MyBatis Generator生成model,dao,mapper
- 关于GPRS模块支持MQTT的选择
- UML 用例图
- Java语法糖系列之枚举类型
- jquery.superslide 参数分析