我們看一下應用程序開發中兩類比較常見的異常情況,第一類是諸如數據庫無法鏈接,配置文件不存在,SQL語句編譯錯誤等的系統級別的異常,一旦這種 異常發生基本上系統無法正常運行。另一類是諸如數據庫中的內容不存在,格式不正確,業務邏輯不滿足要求等的異常,這種異常往往只影響某一條的數據,不會對 系統的正常運行有影響。

Java中的兩類異常

Java中的異常分為兩種類型運行時的異常(RuntimeException)和檢查異常(Checked Exception)。

 

運行時的異常(RuntimeException)可以在程序運行的時候動態的拋出,但是不需要在方法接口中聲明要跑出的運行時異常,也不需要在方 法調用的時候做try-catch處理。系統的運行時異常是指java.lang.RuntimeExceptioin或者他的子類型。 RuntimeException在邏輯上的含義是:

 

檢查異常(Checked Exception)必須要在方法的接口中聲明,并且在使用方法的時候,其拋出的Checked Exception必須使用try-catch處理,檢查異常指的是java.lang.Exception或者他的子類型。

 

注意:有一點需要指出,java.lang.RuntimeException是java.lang.Exception的子類型。所以上述中說的 檢查異常(Checked Exception)指的是java.lang.Exception和其他的非java.lang.RuntimeException子類的子類型。

 

如下代碼展示了RuntimeException的使用:

 

package com.jpleasure.exception;

/**
 * System Exception
 * @author mazhao@dl.cn
 *
 */
public class SystemException extends RuntimeException {

 public SystemException() {
 }

 public SystemException(String message) {
  super(message);
 }

 public SystemException(Throwable cause) {
  super(cause);
 }

 public SystemException(String message, Throwable cause) {
  super(message, cause);
 }
}

以下代碼可以編譯通過,運行的時候拋出異常:

package com.jpleasure.exception;

public class Main {
 public static void main(String ... args ) {
  testRuntimeException();
  
 }
 
 public static void testRuntimeException() {
  
  methodThrowsRuntimeException();
  
 }
 
 private static void methodThrowsRuntimeException() {
  if(true) {
   throw new SystemException("Hello World!");
  }
 }
}

運行的時候輸出內容為:

 Exception in thread "main" com.jpleasure.exception.SystemException: Hello World!
 at com.jpleasure.exception.Main.methodThrowsRuntimeException(Main.java:17)
 at com.jpleasure.exception.Main.testRuntimeException(Main.java:11)
 at com.jpleasure.exception.Main.main(Main.java:5)

以下代碼展示了Exception的使用:

 package com.jpleasure.exception;

/**
 * Application Exception
 * @author mazhao@dl.cn
 *
 */
public class ApplicationException extends Exception {

 public ApplicationException() {
  // TODO Auto-generated constructor stub
 }

 public ApplicationException(String message) {
  super(message);
  // TODO Auto-generated constructor stub
 }

 public ApplicationException(Throwable cause) {
  super(cause);
  // TODO Auto-generated constructor stub
 }

 public ApplicationException(String message, Throwable cause) {
  super(message, cause);
  // TODO Auto-generated constructor stub
 }

}

異常使用代碼:

package com.jpleasure.exception;

public class Main2 {

 /**
  * @param args
  */
 public static void main(String[] args) {
  

 }
 
 public static void testCheckedException() {
  
  try {
   methodThrowsCheckedException();
  } catch (ApplicationException e) {
   // 異常處理代碼
  }
  
 }
 
 private static void methodThrowsCheckedException() throws ApplicationException {
  if(true) {
   throw new ApplicationException("Hello World!");
  }
 }

}

由于ApplicationException是Checked Exception,所以在方法的接口中必須加以聲明,并且在使用的時候必須包括在try-catch代碼塊中。

應用程序開發中的異常

如上述代碼中說明的那樣處于使用方便我們總是將系統異常設置為RuntimeException的子類,在統一的地方處理。

 

為什么要將系統異常設置為Runtime的呢?

 

try-catch塊主要是為了在異常發生的時候有可以挽救的方式,所以會在try部分異常發生的時候進入catch部分,但是系統異常(例如數據 庫無法鏈接,配置文件不存在等)一旦發生基本上沒有挽救的辦法,所以將系統異常聲明為RuntimeException的子類。

另外,系統異常是一種很少會發生的異常,所以在開發中基本不需要考慮,所以將系統異常生命為RuntimeException的子類,這樣在開發的時候基本不需要考慮系統異常發生的情況,只需要統一的做錯誤處理即可。

 

 

應用程序異常通常設置為Checked Exception。需要在使用的地方逐個處理。

 

 

異常消息定義

異常消息通常不會在構造異常的時候傳入,通常情況下在構造異常的時候傳入的是異常消息的編號。

 

編號一般包含的內容有:系統ID,子系統ID,消息類型,流水號等。系統ID,子系統ID,流水號等都比較好理解,那么消息類型是什么呢?我們的消 息常見的有以下一些類型:提示性的,警告性的,錯誤性的。所以我們可以分別以C(Confirm),W(Warnning),E(Error)來區分消息 的類型

 

消息一般存儲在屬性文件(Properties)中使用ResourceBundle類或者Properties類來獲取。當使用到多國語言的錯誤消息的時候需要使用ResourceBundle類。

有些時候也可以存儲在代碼中,這個時候需要使用到ListResourceBundle類。

異常發生時的操作

第一就是要記錄錯誤日志,需要將類,方法,操作數據,異常類型,異常內容的信息記錄下來,便于系統維護人員分析問題數據。

第二及時要拋出錯誤信息,反饋給系統用戶,讓客戶知道系統無法處理他的當前操作。如果有必要還需要提示客戶可能的錯誤情況,希望用戶改善。

 

如何獲得異常的詳細信息

從異常中可以獲得詳細的拋出信息,例如都那些代碼涉及到這個異常,分別在那些類的那些方法中,代碼行數是多少,代碼文件名字是什么等。

例如類LoginLogic調用了LoginDao,而Main調用了LoginLogic,代碼為:

 

package com.jpleasure.exception;

/**
 * Created by IntelliJ IDEA.
 * User: ma.zhao@dl.cn
 * Date: 2007-9-3
 * Time: 22:55:47
 * To change this template use File | Settings | File Templates.
 */
public class LoginDao {
    public void testLogin() throws SystemException {
        if(true) {
            throw new SystemException("System Exception Occurs!");
        }
    }
}

package com.jpleasure.exception;

import java.util.Random;

/**
 * Created by IntelliJ IDEA.
 * User: ma.zhao@dl.cn
 * Date: 2007-9-3
 * Time: 22:56:30
 * To change this template use File | Settings | File Templates.
 */
public class LoginLogic {
    private LoginDao dao = new LoginDao();

    public void testLogin() throws ApplicationException {

        Random randam = new Random(System.currentTimeMillis());
        int randamInt = randam.nextInt();

        if (randamInt % 2 == 0) {
            dao.testLogin();
        } else {
            throw new ApplicationException("Application Exception Occurs!");
        }
    }
}


 

異常處理代碼:

 

package com.jpleasure.exception;

/**
 * Created by IntelliJ IDEA.
 * User: ma.zhao@dl.cn
 * Date: 2007-9-3
 * Time: 22:57:38
 * To change this template use File | Settings | File Templates.
 */
public class Main {
    public static void main(String[] args) {

        LoginLogic logic = new LoginLogic();

        try {
            logic.testLogin();
        } catch (ApplicationException e) {
            printException(e);
        } catch (SystemException e) {
            printException(e);
        }

    }

    private static void printException(Exception e) {
        String msg = e.getMessage();
        System.out.println("exception message:" + msg);
        StackTraceElement[] stes = e.getStackTrace();
        for (int i = 0; i < stes.length; i++) {
            printStackTraceElement(stes[i]);
        }
    }

    
    private static void printStackTraceElement(StackTraceElement ste) {
        String fileName = ste.getFileName();
        String className = ste.getClassName();
        String methodName = ste.getMethodName();
        int line = ste.getLineNumber();
        System.out.println("file:" + fileName + "\t class:" + className + "\t method:" + methodName + "\t line:" + line);
        System.out.println("");
    }
}

 



ExtJS教程- Hibernate教程-Struts2 教程-Lucene教程