//根据 ID 查询数据库
}catch(SQLException e){
//利用非检测异常封装检测异常,降低层次耦合
throw new RuntimeException(SQLErrorCode, e);
}finally{
//关闭连接,清理资源
}
}
### 误区四、忽略异常
如下异常处理只是将异常输出到控制台,没有任何意义。而且这里出现了异常并没有中断程序,进而调用代码继续执行,导致更多的异常。
清单 4
public void retrieveObjectById(Long id){
try{
//..some code that throws SQLException
}catch(SQLException ex){
/**
*了解的人都知道,这里的异常打印毫无意义,仅仅是将错误堆栈输出到控制台。
* 而在 Production 环境中,需要将错误堆栈输出到日志。
* 而且这里 catch 处理之后程序继续执行,会导致进一步的问题*/
ex.printStacktrace();
}
}
可以重构成:
清单 5
public void retrieveObjectById(Long id){
try{
//..some code that throws SQLException
}
catch(SQLException ex){
throw new RuntimeException(“Exception in retieveObjectById”, ex);
}
finally{
//clean up resultset, statement, connection etc
}
}
这个误区比较基本,一般情况下都不会犯此低级错误。
### 误区五、将异常包含在循环语句块中
如下代码所示,异常包含在 for 循环语句块中。
清单 6
for(int i=0; i<100; i++){
try{
}catch(XXXException e){
//….
}
}
我们都知道异常处理占用系统资源。一看,大家都认为不会犯这样的错误。换个角度,类 A 中执行了一段循环,循环中调用了 B 类的方法,B 类中被调用的方法却又包含 try-catch 这样的语句块。褪去类的层次结构,代码和上面如出一辙。
### 误区六、利用 Exception 捕捉所有潜在的异常
一段方法执行过程中抛出了几个不同类型的异常,为了代码简洁,利用基类 Exception 捕捉所有潜在的异常,如下例所示:
清单 7
public void retrieveObjectById(Long id){
try{
//…抛出 IOException 的代码调用
//…抛出 SQLException 的代码调用
}catch(Exception e){
//这里利用基类 Exception 捕捉的所有潜在的异常,如果多个层次这样捕捉,会丢失原始异常的有效信息
throw new RuntimeException(“Exception in retieveObjectById”, e);
}
}
可以重构成
清单 8
public void retrieveObjectById(Long id){
try{
//..some code that throws RuntimeException, IOException, SQLException
}catch(IOException e){
//仅仅捕捉 IOException
throw new RuntimeException(/*指定这里 IOException 对应的错误代码*/code,“Exception in retieveObjectById”, e);
}catch(SQLException e){
//仅仅捕捉 SQLException
throw new RuntimeException(/*指定这里 SQLException 对应的错误代码*/code,“Exception in retieveObjectById”, e);
}
}
### 误区七、多层次封装抛出非检测异常
如果我们一直坚持不同类型的异常一定用不同的捕捉语句,那大部分例子可以绕过这一节了。但是如果仅仅一段代码调用会抛出一种以上的异常时,很多时候没有必要每个不同类型的 Exception 写一段 catch 语句,对于开发来说,任何一种异常都足够说明了程序的具体问题。
清单 9
try{
//可能抛出 RuntimeException、IOExeption 或者其它;
//注意这里和误区六的区别,这里是一段代码抛出多种异常。以上是多段代码,各自抛出不同的异常
}catch(Exception e){
//一如既往的将 Exception 转换成 RuntimeException,但是这里的 e 其实是 RuntimeException 的实例,已经在前段代码中封装过
throw new RuntimeException(/**/code, /**/, e);
}
如果我们如上例所示,将所有的 Exception 再转换成 RuntimeException,那么当 Exception 的类型已经是 RuntimeException 时,我们又做了一次封装。将 RuntimeException 又重新封装了一次,进而丢失了原有的 RuntimeException 携带的有效信息。
解决办法是我们可以在 RuntimeException 类中添加相关的检查,确认参数 Throwable 不是 RuntimeException 的实例。如果是,将拷贝相应的属性到新建的实例上。或者用不同的 catch 语句块捕捉 RuntimeException 和其它的 Exception。个人偏好方式一,好处不言而喻。
### 误区八、多层次打印异常
我们先看一下下面的例子,定义了 2 个类 A 和 B。其中 A 类中调用了 B 类的代码,并且 A 类和 B 类中都捕捉打印了异常。
清单 10
private static Logger logger = LoggerFactory.getLogger(A.class);
public void process(){
try{
//实例化 B 类,可以换成其它注入等方式
B b = new B();
b.process();
//other code might cause exception
} catch(XXXException e){
//如果 B 类 process 方法抛出异常,异常会在 B 类中被打印,在这里也会被打印,从而会打印 2 次
logger.error(e);
throw new RuntimeException(/* 错误代码 */ errorCode, /*异常信息*/msg, e);
}
}
}
public class B{
private static Logger logger = LoggerFactory.getLogger(B.class);
public void process(){
try{
//可能抛出异常的代码
}
catch(XXXException e){
logger.error(e);
throw new RuntimeException(/* 错误代码 */ errorCode, /*异常信息*/msg, e);
}
}
}
同一段异常会被打印 2 次。如果层次再复杂一点,不去考虑打印日志消耗的系统性能,仅仅在异常日志中去定位异常具体的问题已经够头疼的了。
# 文末java面试题,进阶技术大纲,架构资料分享
我将这三次阿里面试的题目全部分专题整理出来,并附带上详细的答案解析,生成了一份**PDF文档**,有兴趣的朋友们[可以点击这里即可免费领取](https://gitee.com/vip204888/java-p7)
* **第一个要分享给大家的就是算法和数据结构**
![网易严选Java开发三面面经:HashMap+JVM+索引+消息队列](https://img-blog.csdnimg.cn/img_convert/9085dbf8d9d275eab39204ef48a2562a.png)
* **第二个就是数据库的高频知识点与性能优化**
![网易严选Java开发三面面经:HashMap+JVM+索引+消息队列](https://img-blog.csdnimg.cn/img_convert/23104399982cb3c920db299e13670822.png)
* **第三个则是并发编程(72个知识点学习)**
![网易严选Java开发三面面经:HashMap+JVM+索引+消息队列](https://img-blog.csdnimg.cn/img_convert/a31ea1be7fdbd3b8ffdb3f1de0efc0d7.png)
* **最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料**
![网易严选Java开发三面面经:HashMap+JVM+索引+消息队列](https://img-blog.csdnimg.cn/img_convert/b8aba59aff00f39f817182f3e1ea3555.png)
e.com/vip204888/java-p7)
* **第一个要分享给大家的就是算法和数据结构**
[外链图片转存中...(img-z4md5bZf-1628063972543)]
* **第二个就是数据库的高频知识点与性能优化**
[外链图片转存中...(img-niOlJ4CU-1628063972546)]
* **第三个则是并发编程(72个知识点学习)**
[外链图片转存中...(img-4jw1rY0Q-1628063972548)]
* **最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料**
[外链图片转存中...(img-J0pzSkid-1628063972550)]
还有更多的Redis、MySQL、JVM、Kafka、微服务、Spring全家桶等学习笔记这里就不一一列举出来