熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

避免在Java中使用Checked Exception

2013-11-23 19:12:25  來源: Java核心技術 

  這篇文章指出了Java中checked Exception的一些缺點提出應該在程序設計中避免使用checked Exception對於需要處理checked Exception的代碼可以使用ExceptionAdapter這個類對checked Exception進行包裝這篇文章的概念和ExceptionAdapter這個類均源自Bruce Eckel的Does Java need Checked Exception

  Java的Exception分為兩類一類是RuntimeException及其子類另外一類就是checked ExceptionJava要求函數對沒有被catch處理掉的checked Exception需要將其寫在函數的聲明部分然而這一要求常常給程序員帶來一些不必要的負擔

  為了避免在函數聲明中寫throws部分在Java項目裡面常常可以看到以下代碼用來吞掉Exception

  

  try {
//
} catch (Exception ex) {
exprintStackTrace();
}

  這顯然不是一個好的處理Exception辦法事實上catch並處理一個Exception意味著讓程序從發生的錯誤(Exception)中恢復過來從這種意義上說已上的代碼只可能在一些很簡單的情況下工作而不帶來問題

  對於很多Exception往往沒有去處理它並讓程序從錯誤中恢復出來的辦法這時唯一能做的事情可能就是在界面上顯示一些提示信息給用戶這種情況下讓程序拋出遇到的Exception是更為合理的做法然而這樣做會使得一些函數的聲明急劇膨脹一個函數可能需要聲明會拋出的個checked Exception而且每個調用它的函數也需要同樣的聲明

  比這更糟糕的是這有可能破壞類設計的openclose原則簡單來說openclose原則是指當擴展一個模塊的時候可以不影響其現有的clientopenclose原則是通過繼承來實現的當繼承一個類的時候我們既擴展了這個類也不會影響原有的client(因為對這個類沒有改動)

  現在考慮下面這種情況有一個父類Base

  

  public class Base {
public void foo() throws ExceptionA {
//
}
}

  現在需要繼承Base這個類並重載foo這個方法在新的實現中foo可能拋出ExceptionB

  

  public class Extend extends Base {
public void foo() throws ExceptionB {
//
}
}

  然而這樣寫在Java裡面是不合法的因為Java把可能會拋出的Exception看作函數特征的一部分子類聲明拋出的Exception必須是父類的子集

  可以在Base類的foo方法中加入拋出ExceptionB的聲明然而這樣就破壞了openclose原則而且有時我們沒有辦法去修改父類比如當重載一個Jdk裡的類的時候

  另一個可能的做法是在Extend的foo方法中catch住ExceptionB然後構造一個ExceptionA並拋出這是個可行的辦法但也只是一個權宜之計

  如果使用RuntimeException這些問題都不會存在這說明checked Exception並不是一個很實用的概念也意味著在程序設計的時候我們應該讓自己的Exception類繼承RuntimeException而不是Exception(這和JDK的建議正好相反但實踐證明這樣做代碼的質量更好

  對於那些需要處理checked Exception的代碼可以利用一個ExceptionAdapter的類把checked Exception包裝成一個RuntimeException拋出ExceptionAdapter來自Bruce Eckel的Does Java need Checked Exception這篇文章在這裡的ExceptionAdapter是我根據JDK 修改過的

  

  public class ExceptionAdapter extends RuntimeException {
public ExceptionAdapter(Exception ex) {
super(ex);
}
 
public void printStackTrace(javaioPrintStream s) {

  getCause()printStackTrace(s);
}

  public void printStackTrace(javaioPrintWriter s) {

  getCause()printStackTrace(s);

  }
// rethrow()的作用是把被包裝的Exception再次拋出

  public void rethrow()
throws Exception
{
throw (Exception) getCause();
}
}


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26435.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.