你会擦屁股吗?——Java擦屁股大法
JE太不给力了,当年这么经典的帖子都给删了,可惜了那么多经典回复
[转]
java的try-finally给我们提供了一个“保证某个动作必然执行”的机会。
一个try-finally结构,只要try块开始执行了,finally块里面的代码保证执行一次并且只有一次。
打个比方,就象你上厕所,只要你一旦开始拉了,我们保证无论如何,是拉稀了也好,放屁了也罢,最终你肯定是擦了屁股
走出卫生间。
应用try-finally,我们可以在异常满天飞的程序里保证我们的关键资源被按时正确清理。一个最常见的应用就是jdbc的
Connection, Statement, ResultSet等。
但是,我最近惊奇地发现,不知道怎么正确清理资源的人大有人在,即使是一些java老手。
看一个例子先:
view plaincopy to clipboardprint?void f(){ Connection conn = ...; Statement stmt = conn.createStatement(); ResultSet rset = ...; ... } void f(){ Connection conn = ...; Statement stmt = conn.createStatement(); ResultSet rset = ...; ... }view plaincopy to clipboardprint?void f(){ Connection conn = ...; Statement stmt = conn.createStatement(); ResultSet rset = ...; rset.close(); conn.close(); ... } void f(){ Connection conn = ...; Statement stmt = conn.createStatement(); ResultSet rset = ...; rset.close(); conn.close(); ... } view plaincopy to clipboardprint?void f(){ Connection conn = ...; Statement stmt = conn.createStatement(); ResultSet rset = ...; rset.close(); stmt.close(); conn.close(); ... } void f(){ Connection conn = ...; Statement stmt = conn.createStatement(); ResultSet rset = ...; rset.close(); stmt.close(); conn.close(); ... } view plaincopy to clipboardprint?void f(){ Connection conn = null; Statement stmt = null; ResultSet rset = null; try{ conn = ...; stmt = ...; rset = ...; ... } finally{ if(rset!=null)rset.close(); if(stmt!=null)stmt.close(); if(conn!=null)conn.close(); } } void f(){ Connection conn = null; Statement stmt = null; ResultSet rset = null; try{ conn = ...; stmt = ...; rset = ...; ... } finally{ if(rset!=null)rset.close(); if(stmt!=null)stmt.close(); if(conn!=null)conn.close(); } } view plaincopy to clipboardprint?void close(Connection conn){ try{ if(conn!=null) conn.close(); } catch(Exception e){ e.printStackTrace(); } } void close(ResultSet rset){ ... } void close(Statement rset){ ... } void f(){ Connection conn = null; Statement stmt = null; ResultSet rset = null; try{ conn = ...; stmt = ...; rset = ...; ... } finally{ close(rset); close(stmt); close(conn); } } void close(Connection conn){ try{ if(conn!=null) conn.close(); } catch(Exception e){ e.printStackTrace(); } } void close(ResultSet rset){ ... } void close(Statement rset){ ... } void f(){ Connection conn = null; Statement stmt = null; ResultSet rset = null; try{ conn = ...; stmt = ...; rset = ...; ... } finally{ close(rset); close(stmt); close(conn); } } view plaincopy to clipboardprint?void f(){ final Connection conn = ...; try{ final Statement stmt = ...; try{ final ResultSet rset = ...; try{ ... } finally{rset.close();} } finally{stmt.close();} } finally{conn.close();} } void f(){ final Connection conn = ...; try{ final Statement stmt = ...; try{ final ResultSet rset = ...; try{ ... } finally{rset.close();} } finally{stmt.close();} } finally{conn.close();} } view plaincopy to clipboardprint?interface ResultListener{ void call(ResultSet rset); } class SqlReader{ void read(ResultListener l){ final Connection conn = ...; try{ final Statement stmt = ...; try{ final ResultSet rset = ...; try{ l.call(rset); } finally{rset.close();} } finally{stmt.close();} } finally{conn.close();} } } interface ResultListener{ void call(ResultSet rset); } class SqlReader{ void read(ResultListener l){ final Connection conn = ...; try{ final Statement stmt = ...; try{ final ResultSet rset = ...; try{ l.call(rset); } finally{rset.close();} } finally{stmt.close();} } finally{conn.close();} } }