AndroidJava try-catch-finally正确用法
目錄
- 一、try-catch-finally的用途
- 二、try-catch的正確使用
- 三、奇怪的try-finally (錯誤的用法)
- 四、關(guān)于try-catch-finally的面試考察
- 1、try、catch、finally 考察,請指出下面程序的運行結(jié)果。
- 2、try、catch、finally 考察2,請指出下面程序的運行結(jié)果。
- 3、try、catch、finally 考察3,請指出下面程序的運行結(jié)果。
一、try-catch-finally的用途
1、異常捕獲;
2、同步鎖的應(yīng)用。
try用于存放要核心代碼,catch捕獲核心代碼發(fā)生的異常,finally用于存放那些無論是否出現(xiàn)異常都一定會執(zhí)行的代碼。在實際使用中,通常用于釋放鎖、數(shù)據(jù)庫連接等資源,把資源釋放方法放到 finally 中,可以大大降低程序出錯的幾率
二、try-catch的正確使用
try{// 核心代碼,如果讀取數(shù)據(jù)庫內(nèi)容 }catch(Exception e){//異常捕獲,例如輸出異常信息}finally{//善后處理,無論是否異常,都會執(zhí)行的部分 }三、奇怪的try-finally (錯誤的用法)
從代碼上看是為了保證鎖的釋放
public void updateChatMsgReadFlag(long time) {mLock.writeLock().lock();try {if (dataBaseManager != null) {dataBaseManager.updateRtChatMsgReadFlag(time);}} finally {mLock.writeLock().unlock();} } try {String sTableName = getChatTableName(mDatabase);String sql = "select * from " + sTableName + " where ("+ ChatColumns.CHAT_RECEIVEUSERID + "=?" + " or "+ ChatColumns.CHAT_SENDUSERID + "=?)" + " and "+ ChatColumns.CHAT_TIME + "<?" + " order by "+ ChatColumns.CHAT_TIME + " desc limit ?";cursor = mDatabase.rawQuery(sql, new String[] { ownerId + "",ownerId + "", timeMillions + "", limit + "" });for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {AbsChatMessage entity = dataToObject(cursor);msgList.add(entity);} } finally {if (cursor != null) {cursor.close();} }從代碼看是保證數(shù)據(jù)庫的cursor得到有效的關(guān)閉。
在項目中看到的代碼,也不知道小伙伴是怎么想的,就把catch給丟掉,咋一看用了try沒有問題,但實際運行中卻異常了,異常是自然的,這種坑多數(shù)情況下要分析堆棧并結(jié)合代碼能找出問題,其次利用工具進(jìn)行codereview,再就是仔細(xì)的人工codereview能發(fā)現(xiàn)。
四、關(guān)于try-catch-finally的面試考察
1、try、catch、finally 考察,請指出下面程序的運行結(jié)果。
public class TryDemo {public static void main(String[] args) {System.out.println(foo());}public static int foo() {try {return 1;} catch (Exception e) {return 2;} finally {System.out.print("3");}} }執(zhí)行結(jié)果:31。
相信很多同學(xué)應(yīng)該都做對了,try、catch。finally 的基礎(chǔ)用法,在 return 前會先執(zhí)行 finally 語句塊,所以是先輸出 finally 里的 3,再輸出 return 的 1。
2、try、catch、finally 考察2,請指出下面程序的運行結(jié)果。
public class TryDemo {public static void main(String[] args) {System.out.println(foo1());}public static int foo1() {try {return 2;} catch (Exception e) {return 1;} finally {return 3;}} }執(zhí)行結(jié)果:3。
這題有點顯難,但也不難,try 返回前先執(zhí)行 finally,結(jié)果 finally 里不按套路出牌,直接 return 了,自然也就走不到 try 里面的 return 了。
finally 里面使用 return 僅存在于面試題中,實際開發(fā)中千萬不要這么用。
3、try、catch、finally 考察3,請指出下面程序的運行結(jié)果。
public class TryDemo {public static void main(String[] args) {System.out.println(test1());}public static int test1() {int i = 0;try {i = 2;return i;} catch (Exception e) {return 1;} finally {i = 3;}} }執(zhí)行結(jié)果:2。
這邊估計有不少同學(xué)會以為結(jié)果應(yīng)該是 3,因為我們知道在 return 前會執(zhí)行 finally,而 i 在 finally 中被修改為 3 了,那最終返回 i 不是應(yīng)該為 3 嗎?確實很容易這么想,我最初也是這么想的,當(dāng)初的自己還是太年輕了啊。
這邊的根本原因是,在執(zhí)行 finally 之前,JVM 會先將 i 的結(jié)果暫存起來,然后 finally 執(zhí)行完畢后,會返回之前暫存的結(jié)果,而不是返回 i,所以即使這邊 i 已經(jīng)被修改為 3,最終返回的還是之前暫存起來的結(jié)果 2。
這邊其實根據(jù)字節(jié)碼可以很容易看出來,在進(jìn)入 finally 之前,JVM 會使用 iload、istore 兩個指令,將結(jié)果暫存,在最終返回時在通過 iload、ireturn 指令返回暫存的結(jié)果。
面試考察部分來自
https://blog.csdn.net/v123411739/article/details/115364158
總結(jié)
以上是生活随笔為你收集整理的AndroidJava try-catch-finally正确用法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python画相关性可视化图_Pytho
- 下一篇: azure mysql on vnet_