<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    新的起點 新的開始

    快樂生活 !

    轉 異?;A知識(來自《《Robust Java》》 )

    Robust Java
    作者: Stephen Stelting
    本書詳細的講述了異常的各個方面的知識,兼帶介紹了測試和調試的基本方法。是了解 Java 異常的極佳教材。

    異常概念
    從某種意義上講,異常就是這樣一種消息:它傳送一些系統問題、故障及未按規定執行的動作的相關信息。異常包含信息,以將信息從應用程序的一部分發送到另一部分。
    異常本身表示消息,指發送者傳給接受者的數據 負荷 。首先,異?;陬惖念愋蛠韨鬏斢杏眯畔?。很多情況下,只需異常對象的類即能識別故障本因并更正問題。其次,異常還帶有可能有用的數據(如屬性)。異常消息或故障本質原因等數據屬于這個范疇。
    在處理異常時,消息必須有接受者;否則將無法處理產生異常的底層問題。


    異常類層次結構
    所有異常有一個共同祖先 Throwable (可拋出)。 Throwable 指定代碼中可用異常傳播機制通過 Java 應用程序傳輸的任何問題的共性。
    Throwable
    有兩個重要的子類: Exception (異常)和 Error (錯誤),二者都是 Java 異常處理的重要子類,各自都包含大量子類。
    異常 是應用程序中可能的可預測、可恢復的問題。 Java API 文檔記錄給出的定義是: 合理應用程序可能需要捕獲的情況。 一般地,大多數異常表示輕度到中度的問題。
    異常一般在特定環境下產生的,通常出現于代碼的特定方法或操作中。
    錯誤 表示運行應用程序中的較嚴重問題。 Java API 文檔記錄給出的定義是 :“ Throwable 的一個子類,代表嚴重問題,合理應用程序不應試圖捕獲它。大多數此類錯誤屬反常情況。
    大多數錯誤與代碼編寫者執行的操作無關,而表示代碼運行時 JVM Java 虛擬機)出現的問題。例如,當 JVM 不再有繼續執行操作所需的內存資源時,將出現 OutOfMemoryError 。
    Exception
    有一個重要的子類 RuntimeException 。 RuntimeException 及其子類表示 “JVM 常用操作 引發的錯誤。例如,若試圖使用空值 對象引用、除數為零,或數組越界,則將分別引發運行時異常( NullPointerException 、 ArithmeticException )和 ArrayIndexOutOfBoundException 。


    異常的處理或聲明選項
    在處理潛在故障時,有兩個選項。在調用可能引發異常的方法時,可以捕獲異常,也可以聲明該方法拋出異常。也就是說的 處理( handle )或聲明( declare 規則。

    處理異常: try catch finally
    若要捕獲異常,則必須在代碼中添加異常處理器塊。

    import java.io.*;

    public class EchoInputTryCatchFinally{
    ??? public static void main(String [] args) {
    ??? ??? System.out.println("Enter text to echo");
    ??? ??? InputStreamReader isr = new InputStreamReader(System.in);
    ??? ??? BufferedReader inputReader = new BufferedReader(isr);
    ??? ??? try{
    ??? ??? ??? String inputLine = inputReader.readLine();
    ??? ??? ??? System.out.println("READ: "+inputLine);
    ??? ??? }
    ??? ??? catch(IOException exc){
    ??? ??? ??? System.out.println("Exceptin encountered: "+exc);
    ??? ??? }
    ??? ??? finally{
    ??? ??? ??? System.out.println("My job here is done.");
    ??? ??? }
    ??? }
    }

    1.try

    在將一個或多個語句放入 try 塊時,則表示這些語句可能拋出異常。編譯器知道可能要發生異常,于是用一個特殊結構評估塊內所有語句。

    2.catch

    問題出現時,一種選擇是定義代碼塊來處理問題, catch 的目的便在與此。 catch 塊是 try 塊所產生異常的接受者。基本原理為:一旦生成異常,則 try 塊的執行中止, JVM 將查找相應的 catch 塊。在 try-catch 結構中,可能有多個 catch 塊;此時,異常將交由第一個匹配的 catch 處理。

    3.finally

    還可以定義這樣 一個代碼塊,無論試圖運行 try 塊代碼的結果如何,該塊一定運行。 finally 塊作用便在于此。在常見的所有環境中, finally 塊都將運行。無論 try 塊是否運行完,無論是否產生異常,也不論異常是否在 catch 塊得到處理, finally 塊都將運行。
    ???

    try-catch-finally
    的規則
    ·
    必須在 try 之后添加 catch 塊??扇我饨硬唤?/span> finally 塊。
    ·
    必須遵守塊順序:如代碼同時使用 catch finally 塊,則必須將 catch 塊放在 try 塊之后。
    · try
    塊與相應的 catch finally 之間可能不存在語句。
    · catch
    塊與特定異常類的類型相關。
    ·
    一個 try 塊可能有多個 catch 塊。若如此,將執行第一個匹配塊。有一個經驗法則:要按從最具體到最一般的順序組織處理塊。
    ·
    除下列情況,總將執行 finally 作為結束:
    ??? ??? a.JVM
    過早中止(調用 System.exit(int)
    ??? ??? b.
    finally 塊中拋出一個未處理的異常。
    ??? ??? c.
    計算機斷電、失火,或遭遇病毒攻擊。
    ·
    可嵌套 try-catch-finally 結構
    ·
    try-catch-finally 結構中,可重新拋出異常。



    聲明異常
    若要聲明異常,則必須將其添加到方法簽名塊的結束位置,即輸入部分之后。以下是一個異常聲明方法的示例:
    public void errorProneMethod(int input) throws java.io.IOException {
    ??? ...
    }
    這樣,聲明的異常將傳給方法調用者,而且也通知了編譯器;該方法的任何調用者必須遵守處理或聲明規則。

    聲明異常的規則
    ·
    必須聲明方法可能拋出的任何可檢測異常( checked exception )。
    ·
    非檢測異常( unchecked exception )不是必須的,可聲明,也可不聲明。
    ·
    調用方法必須遵守任何可檢測異常的處理或聲明規則。若覆蓋一個方法,則不能聲明與覆蓋方法不同的異常。聲明任何異常必須被覆蓋方法所聲明異常的同類或子類。



    可檢測異常和非可檢測異常
    Java
    的可檢測異常和非檢測異常涇渭分明。可檢測異常經編譯器驗證,對于聲明拋出異常的任何方法,編譯器將強制執行處理或聲明規則。
    非檢測異常不遵循處理或聲明規則。在產生此類異常時,不一定非要采取任何適當操作,編譯器不會檢查是否已解決這樣一個異常。有兩個主要類定義非檢測異常: RuntimeException Error 。
    什么 Error 子類屬于非檢測異常?這是因為無法預知它們的產生時間。若 Java 應用程序內存不足,則隨時可能出現 OutOfMemoryError ;起 因一般不是應用程序中的特殊調用,而是 JVM 自身的問題。另外, Error 類一般表示應用程序無法解決的嚴重問題,故將這些類視為非檢測異常。
    RuntimeException
    類也屬于非檢測異常,一個原因是普通 JVM 操作引發的運行時異常隨時可能發生。與 Error 不同,此類異常一般有特定操作引發,但這些操作在 Java 應用 程序會頻繁出現。另一個原因是:它們表示的問題不一定作為異常處理??梢栽?/span> try-catch 結構中處理 NullPointerException ,但若 在使用引用前測試空值,則更簡單經濟。


    異常處理技術和實踐

    選擇處理或聲明
    一個經驗法則是:
    盡可能去處理異常,如果沒有能力處理就聲明異常。
    從本質上將,僅當方法缺少自我處理異常的信息、上下文或資源時,才將異常信息傳給調用者。

    標準異常處理選項
    對于處理器代碼塊捕獲的大多數錯誤情況,一般可以采用以下 9 種響應方式:
    ·
    記錄異常和相關信息
    ·
    要求用戶或應用程序輸入信息
    ·
    使用默認值或替換數據
    ·
    將控制轉移到應用程序的其他部分
    ·
    將異常轉換為其他形式
    ·
    忽略問題
    ·
    重試操作
    ·
    采取替換或恢復操作
    ·
    使系統作好停止準備


    記錄異常和相關信息
    為有效處理異常,日志記錄( logging )是最有效的工具之一。這有利于系統的長期開發和維護,有助于完成系統恢復、測試和調試等任務。一般要記錄信息,可使用下列方法:
    ??? ·
    標準輸出或標準錯誤流
    ??? ·
    自定義記錄類
    ??? · Java
    記錄 API

    1.
    標準輸出或標準錯誤流
    對于簡單的記錄任務,可使用標準輸出或錯誤流: System.out 、 System.err 。
    System.out.println("User error: replace user and continue");
    System.err.println("Press any key. Go on. I dare ya.");
    因為 System 類允許通過方法調用 System.setOut(PrintStream) System.setErr(PrintStream), 將輸出重定向到另一個目標位置,所以能夠滿足基本文件輸出等的需要。
    此類功能一般適用于簡單應用程序的本地記錄。而對于較復雜的應用程序,使用這些功能工作量過大。此外,一些 Java 代碼類型運行在服務器的 JVM 中,不允許將輸出定向到這些位置。

    2.
    自定義記錄類
    一些應用程序要求記錄更靈活,更易配置。此時,應為系統開發記錄資源(即開發一個類)來接受應用程序范圍內的調用,并將它們記錄到一個中心位置。這樣的類常實現為靜態資源或單模式( Singleton ),以確保通用于系統,而不需要其他對象包含其引用。

    import java.io.*;
    import java.util.*;

    public class CustomLogger {
    ??? private static final String DEFAULT_FILE="exceptions.log";
    ??? private static final String FILE_KEY="application.logfile";
    ??? private static CustomLogger instance = new CustomLogger();
    ??? private static PrintWriter outputLog;
    ???
    ??? private CustomLogger() {
    ??? ??? String filename = System.getProperty(FILE_KEY,DEFAULT_FILE);
    ??? ??? try{
    ??? ??? ??? outputLog = new PrintWriter(new FileWriter(filename,true));
    ??? ??? }
    ??? ??? catch (IOException exc) {
    ??? ??? ??? exc.printStackTrace();
    ??? ??? }
    ??? }

    ??? public static CustomLogger getInstance() {
    ??? ??? return instance;
    ??? }

    ??? public void log(String message) {
    ??? ??? logMessage(new Date() + " " + message);
    ??? }

    ??? public void log(Throwable error) {
    ??? ??? StringBuffer message = new StringBuffer(new Date() + " ERROR: "+ error.getClass().getName()+ System.getProperty("line.separator"));
    ??? ??? message.append(error);
    ??? ??? logMessage(message.toString());
    ??? }

    ??? private void logMessage(String message) {
    ??? ??? outputLog.println(message);
    ??? ??? outputLog.flush();
    ??? }
    }

    3.Java
    記錄 API
    JDK1.4 中, Sun 引入了記錄 API ,以更靈活有效地記錄錯誤、消息和通知。一般地,使用 java.util.logging 包中的幾個類即可執行簡單的記錄任務。例如,若要將消息發送到標準輸出,則代碼如下所示:
    Logger logException = Logger.getLogger("basic.exception.example");
    logExcetption.log(Level.WARNING, "Unable to find configuration file.");
    也可以方便地設置易于閱讀的日志文件:
    Logger logException = Logger.getLogger("exception.example");
    try{
    ??? Handler fileOut = new FileHandler("exc.err",true);
    ??? fileOut.setFormatter(new SimpleFormatter());
    ??? logException.addHadndler(fileOut);
    }
    catch (IOException ex) {
    ??? //....
    }
    logException.log(Level.WARNING,"Exception generated");


    要求用戶或應用程序輸入信息
    于與最終用戶 接近 的問題,最好讓用戶來確定響應應用程序相應問題的方式。這一般通過 GUI 管理,使用戶作出選擇或輸入信息。對于簡單故障,用戶可能僅 需確定適當的操作序列;而對于較復雜的問題,則可能要添加附加或替換信息。很多 GUI 使用對話框來提示用戶作出決策,在 AWT 中,可使用 java.awt.Dialog 類;在 Swing API 中,一般使用 javax.swing.JDialog javax.swing.JOptionPane 。下面的示例代碼顯示了在出現錯誤時如何要 求用戶輸入信息:
    private void showConfigErrorMessage() {
    ??? String msg = "Unable to load user preferences file: create new file?";
    ??? String title = "Application Error";
    ??? int result = JOptionPane.showConfirmDialog(null,msg,title,JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
    ??? if(result == JOptionPane.YES_OPTION) {
    ??? ??? creatNewConfigFile();
    ??? }
    ??? else{
    ??? ??? loadDefaultSettings();
    ??? }
    }


    使用默認值或替換數據
    果使用替換或默認值,那么,即使在執行操作時遇到異常,程序仍可繼續運行。在通信示例中。另一臺服務器(或同一臺服務器上的不同端口)可能是一個合適的替 換方案。若有可識別的任何標準值,則可以在應用程序中包含默認值。在最簡單的情況下,可以將這些值作為應用程序中的常量(靜態最終值):
    private static final String ALTERNATE_HOST = "denver";
    private static final int ALTERNATE_PORT = 5280;
    更復雜一些的選項是允許默認值存儲在配置文件中,并在運行時加載到應用程序。
    private static final String ALTERNATE_HOST = "denver";
    private static final String HOST_KEY = "client.app.host";

    public void sendData(String host,int port,Serializable information, String propertyFile){
    ??? if(communication ==null){
    ??? ??? communication = new ClientNetWork();
    ??? }

    ??? try{
    ??? ??? communication.connect(host,port);
    ??? ??? conmunication.sendData(information);
    ??? }
    ??? catch( IOException exc){
    ??? ??? Properties serverProps = new Properties();
    ??? ??? try{
    ??? ??? ??? FileInputStream input = FileInputStream(propertyFile);
    ??? ??? ??? serverProps.load(input);
    ??? ??? ??? String serverName = serverProps.getProperty(HOST_KEY,ALTERNATE_HOST);
    ??? ??? ??? sendData(serverName,port,information);
    ??? ??? }
    ??? ??? catch(IOException exc2) {
    ??? ??? ??? exc.printStackTrace();
    ??? ??? }
    ??? }
    }


    將控制轉移到應用程序的其他部分
    還有一種將異常處理職責傳給系統另一部分的非終極方式:不是從異常產生方法完全委托,而是開發一個異常處理類,使用它來集中處理應用程序代碼。
    private void saveOrderInfo(OrderInfo info){
    ??? try{
    ??? ??? OrderService.getInstance().saveOrderInfoToFile(info);
    ??? }
    ??? catch(IOException exc)
    ??? {
    ??? ??? handleFileSaveError(info);
    ??? }
    }


    將異常轉換為其他形式
    時,最好將異常轉化為其他形式,以將異常更改為對應用程序更有意義的形式,提供更適當的上下文以準確描述錯誤。由于可將原始異常包裝到另一個異常中(從 JDK1.4 開始),故不會失去原始異常的上下文或數據。下例顯示解決 saveOrderInfo 方法產生的 IOException 的另一種方法: catch 塊將異常轉化為 OrderException 拋給方法調用者。
    private void saveOrderInfo(OrderInfo info) throws OrderException{
    ??? try {
    ??? ??? OrderService.getInstance().saveOrderInfoToFile(info);
    ??? }
    ??? catch(java.io.IOException exc) {
    ??? ??? throw new OrderException("File I/O error when saving ORderInfo",exc);
    ??? }
    }

    忽略問題
    意,不能濫用這種方法,否則,代碼將出現嚴重問題。確實存在這樣的情況,即一個異常對應用程序的所有其他部分沒有任何影響。例如,在調用 I/O 流的關閉方 法時產生的異常便屬于這種類型。該方法可拋出表示問題的 IOException ,但應用程序除了記錄事件之外,一般什么也不做。
    //Declare member variable sourceFile in the class
    private FileReader souceFile;
    //...
    ??? try{
    ??? ??? sourceFile.close();
    ??? }
    ??? catch (java.io.IOException exc) {
    ??? ??? //...
    ??? }


    重試操作
    有些情況下,最適當的操作是在等一段時間后重試操作。在試圖連接到服務器或數據庫時,有時會發生異常,因為服務器的信息量過大。此時,最好再等一段時間,再嘗試連接。
    try{
    ??? clientNetwork.connect("www.talk-about-tech.com",5280);
    }
    catch (java.io.IOException exc)
    {
    ??? try {
    ??? ??? Thread.sleep(10000);
    ??? }
    ??? catch (InterruptedException exc2) {}

    ??? try{
    ??? ??? clientNetwork.connect("www.talk-about-tech.com",5280);
    ??? }
    ??? catch (java.io.IOException exc)
    ??? {
    ??? ??? //...
    ??? }
    }


    采取替換或恢復操作
    有時,可采取補償方式來處理異常。例如,若不能連接服務器,則可以在本地緩存數據,并在之后某一段時間將數據發送到服務器。理想情況下,恢復操作將允許應用程序正常運行。
    try{
    ??? svr.connect("www.talk-about-tech.ocm",5280);
    }
    catch (IOException exc)
    {
    ??? enableFileCache();
    }


    使系統作好停止準備
    如果某一異常確實是應用程序的關鍵錯誤,則需要采取步驟,使系統作好停止準備。這種情況下,要確保該應用程序不致使系統的其他部分出現故障,也不會使數據處于不一致狀態,這就需要完成以下幾件事情:
    ??? ·
    若有打開的文件,則關閉它
    ??? ·
    若有基于連接的資源,則采用普通方式關閉
    ??? ·
    若有需要保持一致的信息,則一定要保存
    ??? ·
    根據需要,通知應用程序、客戶端或子系統應用程序將結束。



    處理異常時提倡的事情

    盡可能地處理異常
    要盡量處理處理異常,如果條件確實不允許,無法在自己的代碼中完成處理,就考慮聲明異常。如果人為避免在代碼中處理異常,僅做聲明,則是一種錯誤和懶惰的實踐。

    具體問題具體解決
    異常的部分優點在于能為不同類型的問題提供不同的處理操作。有效異常處理的關鍵是識別特定故障場景,并開發解決此場景的特定相應行為。為了充分利用異常處理能力,需要為特定類型的問題構建特定的處理器塊。

    記錄可能影響應用程序運行的異常
    至少要采取一些永久方式,記錄下可能影響應用程操作的異常。理想情況下,當然是在第一時間解決引發異常的基本問題。不過,無論采用什么處理操作,一般總應記錄下潛在的關鍵問題。別看這個操作非常簡單,但可以幫助您用很少的時間來跟蹤應用程序復雜的問題起因。

    根據情況將異常轉換為業務上下文
    構建異常成本不高,所以,若要通知一個應用程序特有的問題,有必要將應用程序轉換為不同形式。若用業務特定狀態表示異常,則代碼更易維護。 J2SE 1.4 的異常有所增強,允許包裝原始異常,故不會失去問題的原始上下文。



    處理異常是忌諱的事項

    一般不要忽略異常
    在異常處理塊中,一項最危險的舉動是 不加通告 地處理異常。如下所示:
    try {
    ??? Class.forName("business.domain.Customer");
    }
    catch (ClassNotFoundException exc) {}
    經常能夠在代碼中看到類似的代碼塊。有人總喜歡在編寫代碼簡單快速地編寫空處理塊,并 自我安慰地 宣稱準備在 后期 添加恢復代碼,但這個 后期 最終成了 無期
    這種做法有什么壞處?如果異常對應用程序的其他部分確實沒有任何負面影響,這未嘗不可。但事實往往并非如此,異常會擾亂應用程序的狀態;此時,這樣的代碼塊無異于掩耳盜鈴。

    不要使用覆蓋式異常處理塊
    另一個危險的處理實踐式覆蓋式處理器( blanket handler )。該代碼的基本結構如下所示:
    try{
    ??? //...
    }
    catch (Exception e) {
    ??? //...
    }
    使用覆蓋式異常處理塊有以下兩個前提之一:
    ·
    代碼中只有一類問題。
    ???
    這可能正確,但即便如此,也不應該使用覆蓋式處理,捕獲更具體的異常形式有利無弊。
    ·
    單個恢復操作始終適用。
    ???
    這幾乎絕對錯誤。幾乎沒有哪個方法能放之四海而皆準,能應付出現的任何問題。
    分析一下這樣編寫代碼將發生的情況。只要方法不斷拋出預期的異常集,則一切正常。但是,如果方法拋出了未預料到的異常,則無法看到要采取的操作。當覆蓋式處理器對新異常類型執行千篇一律的任務時,只能間接看到異常處理結果。如果代碼沒有打印或記錄語句,則根本看不到結果。
    更糟的是,當代碼發生變化時,覆蓋式處理器將繼續作用于所有新的異常類型,并以相同方式處理所有類型。一般地,在修改代碼時,這是不智之舉 —— 要考慮方法更改所產生的影響,并相應更改異常處理塊。

    一般不要將特定異常轉換為更通用的異常
    將特定異常轉換為更通用異常是一種錯誤做法。一般而言,這將取消異常起初拋出時產生的上下文,在將異常傳到系統的其他位置時,將更難處理。見下例:
    try{
    ??? //error-prone code
    }
    catch (IOException e) {
    ??? String msg = "If you didn't have a problem before, you do now!";
    ??? throw new Exception(msg);
    }
    為沒有原始異常的信息,所以處理器塊無法確定問題的起因,也不知如何更正問題。更糟的是,該方法必須聲明它拋出 Exception ,實際上,這形同虛設, 對該方法的 Java 文檔讀者沒有任何幫助作用。對于拋出通用 Exception 對象的方法,應執行哪種恢復操作?一般而言,若要重新拋出異常,要有 3 個理 由:
    ??? ·
    重新拋出同一異常,以采取一些操作,然后傳送異常作進一步處理。
    ??? ·
    包裝或重新拋出更具體的異常類型,以縮小后續處理器的問題類型。
    ??? ·
    包裝或重新拋出不同類型的異常,轉換為適當上下文,提供給不同應用程序子系統的處理器。在轉換為業務異常時,一般會這樣做。

    不要處理能構避免的異常
    于有些異常類型,實際上根本不必處理。一般地,要秉持這樣一個理念:為不可避免的錯誤使用異常。雖然可用異常來處理形形色色的各種問題,但不一定非要這么 做。處理或聲明異常必然會影響代碼的運行效率。也就是說,若能避免某些問題類型,則成本比使用異常來解決要低。諸如處理空指針等問題。





    高級異常處理概念

    自定義異常
    使用子定義異常有什么好處呢?創建自定義異常是為了表示應用程序的一些錯誤類型,為代碼可能發生的一個或多個問題提供新的含義??梢燥@示代碼多個位置之間的錯誤的相似性,也可區分代碼運行時可能出現的相似問題的一個或多個錯誤,或給出應用程序中一組錯誤的特定含義。
    創建和使用自定義異常并不難。遵循以下 3 個步驟即可。

    1.
    定義異常類
    一般要定義新類來表示自定義異常。多數情況下,只需創建已有異常類的子類。
    public class CustomerExistsException extends Exception {
    ??? public CustomerExistException() { }
    ??? public CustomerExistException(String message) {
    ??? ??? super(message);
    ??? }
    }
    至少要繼承 Throwable Throwable 的子類。經常要定義一個或多個構造函數,以在對想中存儲錯誤消息。在繼承任何異常時,將自動繼承 Throwable 類的一些標準特性,如:
    ??? ·
    錯誤消息
    ??? ·
    棧跟蹤
    ??? ·
    異常包裝
    若要在異常中添加附加信息,則可以為類添加一些變量和方法:
    public class CustomerExistsException extends Exception
    {
    ??? private String customerName;
    ??? public CustomerExistsException() {}
    ??? public CustomerExistsException(String message) {
    ??? ??? super(message);
    ??? }
    ??? public CustomerExistsException(String message, String customer){
    ??? ??? super(message);
    ??? ??? customerName = customer;
    ??? }
    ??? public String getCustomerName() {
    ??? ??? return customerName;
    ??? }
    }
    由本例可知,可修改 CustomerExistsException 類,以支持其他屬性。例如,可將 customerName 字符串(引發異常的記錄的客戶名)與異常聯系起來。

    2.
    聲明方法拋出自定義異常
    這實際上時 處理或聲明 規則的 聲明 部分。為了使用自定義異常,必須通知調用代碼的類:要準備處理這個異常類型。為此,聲明一個或多個方法拋出異常:
    public void insertCustomer(Customer c) throws CustomerExistsException {
    ??? //...
    }

    3.
    找到故障點,新建異常并加上關鍵子 throw
    最后一步實際上是創建對象,并通過系統傳送該對象。為此,需要了解代碼將在方法的哪個位置出現故障。根據情況,可能要使用以下部分或所有條件,來指示代碼中的故障點。
    ??? (1)
    外部問題
    ??? ??? ·
    應用程序中產生的異常
    ??? ??? ·
    其他方法返回的故障代碼
    ??? (2)
    內部問題
    ??? ??? ·
    應用程序狀態不一致
    ??? ??? ·
    應用程序中的處理問題



    子類
    構建子類時,可以覆蓋父類的方法,此時,必須遵守一些嚴格的規則。必須復制方法的簽名:方法名、輸入和輸出都要匹配。不能使覆蓋的方法比父類更私有。還要 注意,方法不能拋出父類方法未聲明的異常。也就是說,在覆蓋方法時,可拋出與父類的方法相同的異?;虍惓5淖蛹H绻诟割惙椒ㄖ形炊x,則不能拋出不同 的異常。

    接口和抽象類的異常聲明
    抽象方法只提供方法簽名,不真正定義任何代碼;接口實際上全部由抽象方法組成。為這類方法定義異常時,實際上是在設置一種期望,描述最終實現的方法可能出現的錯誤。
    public interface CommunicationServer {
    ??? public void processClient() throws ServerConnectException;
    ??? public void listen();
    }



    Java
    核心語言中的異常

    基本數據類型的常見問題
    1.
    不允許在布爾和數值類型間轉換
    Java 中,布爾變量不能轉換為其他任何基本數據類型。也就是說,不能聲明這樣一個方法,它返回整型,并將結果視為布爾值。

    2.
    數值數據類型的數據截斷
    在兩種情況下,可能出現這個問題:收縮轉換和數學運算。
    強制轉換:
    int i = 2048;
    byte b = (byte)i;
    數學運算:
    int i,j,k;
    i = 10000;
    j = 400000;
    k = i * j;

    3.
    數值數據類型的精度丟失
    例:
    double c= 0.025;
    double d= 21.003;
    double e=c*d;
    System.out.println("c ="+c+", d="+d);
    System.out.println("c*d="+e);
    本例中,輸出的乘積是 0.5250750000000001 。這個問題出現的是舍入錯誤??刹捎脦追N方案來消除這個問題。如果要在操作小數值時確保精度, 則使用 BigDecimal 類。如果僅要求格式符合輸出要求,則可用 java.lang.format 包中的類來處理舍入。

    4.
    數學運算和 ArithmeticException
    除零錯誤。

    一般建議
    · 預先了解應用程序的數據要求,并制定相應規劃。選項有:
    ??? a.
    使用 BigDecimal BigInteger 。
    ??? b.
    選擇一種足夠大、足夠精確,可以滿足需要的存儲類型。
    ·
    在使用 / 或%運算符時,檢查操作數中的 0 值。
    ·
    在顯示值時,使用滿足需要的策略。選項有:
    ??? a.
    原始基本類型用于基本需要。
    ??? b. BigDecimal
    BigInteger 用于擴展精度。
    ??? c. NumberFormat
    用于準確格式控制。

    posted on 2007-03-19 11:06 advincenting 閱讀(401) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    公告

    Locations of visitors to this pageBlogJava
  • 首頁
  • 新隨筆
  • 聯系
  • 聚合
  • 管理
  • <2007年3月>
    25262728123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    統計

    常用鏈接

    留言簿(13)

    隨筆分類(71)

    隨筆檔案(179)

    文章檔案(13)

    新聞分類

    IT人的英語學習網站

    JAVA站點

    優秀個人博客鏈接

    官網學習站點

    生活工作站點

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲综合一区二区国产精品| 日本中文字幕免费高清视频| 亚洲一区二区在线免费观看| 国产无遮挡色视频免费视频| 最近2019年免费中文字幕高清| 色多多A级毛片免费看| 亚洲国产乱码最新视频| 亚洲第一精品在线视频| 在线观看亚洲成人| 国产高清免费观看| 好吊妞在线成人免费| 1a级毛片免费观看| 免费精品一区二区三区第35| 九九久久精品国产免费看小说 | 成人久久免费网站| 日韩在线观看免费| 高潮毛片无遮挡高清免费| 亚洲va久久久久| 亚洲伊人精品综合在合线| 亚洲人成在线观看| 亚洲A∨无码一区二区三区| 久久亚洲国产精品123区| 亚洲精品乱码久久久久久不卡| 国产精品免费_区二区三区观看| 免费毛片在线看片免费丝瓜视频 | 亚洲成人一级电影| 91嫩草私人成人亚洲影院| 亚洲精品高清国产一久久| 久久亚洲精品成人AV| 亚洲视频在线观看免费| 亚洲天天在线日亚洲洲精| 一区二区三区亚洲| 亚洲欧洲日产v特级毛片| 亚洲乱码日产精品BD在线观看| 亚洲国产成人超福利久久精品| 亚洲中文无码a∨在线观看| 亚洲天堂男人影院| 亚洲AV色无码乱码在线观看| 成a人片亚洲日本久久| 十八禁的黄污污免费网站| 亚洲精品视频免费观看|