我们看一下应用程序开发中两类比较常见的异常情况,第一类是诸如数据库无法链接,配置文件不存在,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教程