Java异常处理的最佳实践
1、要在方法定义分句中定义具体的异常
按照public FileInputStream testMethod1() throws Exception{这种写法,表示该方法会抛出所有受检查异常,这不是一个良好的编程习惯。在这种情况下,我们最好抛出足够具体的异常,以便调用者进行合适的捕获和处理,例如public FileInputStream testMethod1() throws IOException{
例如,如果一个模块抛出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 extends Exception{ public ExampleException1(String s, Throwable t){ super(s,t); } public ExampleException1(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); throw e; }
记录和抛出异常会在日志文件中产生多条日志消息,代码中存在单个问题
9、finally块中永远不要抛出任何异常
try { someMethod(); //Throws exceptionOne } finally { cleanUp(); //如果finally还抛出异常,那么exceptionOne将永远丢失 }
10、记住“早throw晚catch”原则
应该尽快抛出(throw)异常,并尽可能晚地捕获(catch)它。 你应该等到你有足够的信息来妥善处理它。
11、优先捕获最具体的异常
优先捕获最具体的异常类,并将不太具体的 catch 块添加到列表的末尾
浙公网安备 33010602011771号