在调用其他模块时,最好捕获由该模块抛出的具体的异常。如果某个被调用模块抛出了多个异常,那么只捕获这些异常的父类是不好的编程习惯。
例如,如果一个模块抛出FileNotFoundException和IOException,那么调用这个模块的代码最好写两个catch语句块分别捕获这两个异常,而不要只写一个捕获Exception的catch语句块。
正确的写法如下:
try{//some statements
catch(FileNotFoundException e){//handle here
}catch(IOException e){//handle here
}
3、记得在finally语句块中释放资源
在代码中建立数据库连接、文件操作符或者其他需要被及时释放的系统资源,如果没有及时释放这些资源,会影响到系统的性能。为了避免这种情况发生,可以使用Java 7的try(open the resources) {deal with resources}语句,如果还是习惯这种老式写法,则可以按照如下方式写:
finally{try{if (con != null) {
con.close();
}if (stat != null) {
stat.close();
}
}catch(SQLException sqlee) {
sqlee.printStackTrace();
}
}
4、异常会影响性能
异常处理的性能成本非常高,创建一个异常非常慢,抛出一个异常又会消耗1~5ms,当一个异常在应用的多个层级之间传递时,会拖累整个应用的性能。
5、正确得包装异常类型
当需要在应用重新抛出异常时,应该正确得包装原始异常,否则会丢失原始异常
try{throw new IOException("IOException");
}catch(IOException e){throw new ExampleException("Example Exception and " +e.getMessage());
}class ExampleException extendsException{publicExampleException1(String s, Throwable t){super(s,t);
}publicExampleException1(String s){super(s);
}
}
IOException的调用栈已经丢失,因为我们在catch语句块中没有正确包装IOException。若将catch语句块修改成下面这样,这可以发现原始异常的调用栈也被打印出来。
catch(IOException e){throw new ExampleException1("Example Exception",e);
}
6、不要使用异常控制程序的流程
不应该使用异常控制应用的执行流程,例如,本应该使用if语句进行条件判断的情况下,你却使用异常处理,这是非常不好的习惯,会严重影响应用的性能。
7、在你的方法里抛出定义具体的检查性异常
public void foo() throws SpecificException1, SpecificException2 { //正确方式
}
8、要么记录异常要么抛出异常,但不要一起执行
catch(NoSuchMethodException e) {//错误方式
LOGGER.error("Some information", e);throwe;
}
记录和抛出异常会在日志文件中产生多条日志消息,代码中存在单个问题
9、finally块中永远不要抛出任何异常
try{
someMethod();//Throws exceptionOne
} finally{
cleanUp();//如果finally还抛出异常,那么exceptionOne将永远丢失
}
10、记住“早throw晚catch”原则
应该尽快抛出(throw)异常,并尽可能晚地捕获(catch)它。 你应该等到你有足够的信息来妥善处理它。
11、优先捕获最具体的异常
优先捕获最具体的异常类,并将不太具体的 catch 块添加到列表的末尾