目录
一、try-catch-finally的用途
1、异常捕获;
2、同步锁的应用。
try用于存放要核心代码,catch捕获核心代码发生的异常,finally用于存放那些无论是否出现异常都一定会执行的代码。在实际使用中,通常用于释放锁、数据库连接等资源,把资源释放方法放到 finally 中,可以大大降低程序出错的几率
二、try-catch的正确使用
try{
// 核心代码,如果读取数据库内容
}catch(Exception e){
//异常捕获,例如输出异常信息
}finally{
//善后处理,无论是否异常,都会执行的部分
}
三、奇怪的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();
}
}
从代码看是保证数据库的cursor得到有效的关闭。
在项目中看到的代码,也不知道小伙伴是怎么想的,就把catch给丢掉,咋一看用了try没有问题,但实际运行中却异常了,异常是自然的,这种坑多数情况下要分析堆栈并结合代码能找出问题,其次利用工具进行codereview,再就是仔细的人工codereview能发现。
四、关于try-catch-finally的面试考察
1、try、catch、finally 考察,请指出下面程序的运行结果。
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");
}
}
}
执行结果:31。
相信很多同学应该都做对了,try、catch。finally 的基础用法,在 return 前会先执行 finally 语句块,所以是先输出 finally 里的 3,再输出 return 的 1。
2、try、catch、finally 考察2,请指出下面程序的运行结果。
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;
}
}
}
执行结果:3。
这题有点显难,但也不难,try 返回前先执行 finally,结果 finally 里不按套路出牌,直接 return 了,自然也就走不到 try 里面的 return 了。
finally 里面使用 return 仅存在于面试题中,实际开发中千万不要这么用。
3、try、catch、finally 考察3,请指出下面程序的运行结果。
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;
}
}
}
执行结果:2。
这边估计有不少同学会以为结果应该是 3,因为我们知道在 return 前会执行 finally,而 i 在 finally 中被修改为 3 了,那最终返回 i 不是应该为 3 吗?确实很容易这么想,我最初也是这么想的,当初的自己还是太年轻了啊。
这边的根本原因是,在执行 finally 之前,JVM 会先将 i 的结果暂存起来,然后 finally 执行完毕后,会返回之前暂存的结果,而不是返回 i,所以即使这边 i 已经被修改为 3,最终返回的还是之前暂存起来的结果 2。
这边其实根据字节码可以很容易看出来,在进入 finally 之前,JVM 会使用 iload、istore 两个指令,将结果暂存,在最终返回时在通过 iload、ireturn 指令返回暂存的结果。
面试考察部分来自
https://blog.csdn.net/v123411739/article/details/115364158