D盘

workspace
posts - 165, comments - 53, trackbacks - 0, articles - 0
  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

来自:http://book.csdn.net/bookfiles/150/1001506504.shtml

3.1  简介

前两章介绍了使用异常的基本概念,重点讨论了处理方式和理由,阐述了工作原理,分析如何在代码中处理异常。本章介绍更高级的主题,具体内容如下:

       如何创建和使用自定义异常。

       异常支持链表和本地化。

       抽象类和接口中的异常用法。

       覆盖方法的异常要求。

       如何用字节码表示异常处理代码。

       应用程序中异常处理操作的效率。

在处理异常时,上述主题并不常用。简单项目根本不使用它们。但在编写较复杂的程序时,这些主题的作用便显示出来了。

3.2  自定义异常

前面讨论了如何处理调用Java API的方法时产生的异常。根据需要,还可创建和使用自定义异常——自我构建表示错误的类。可创建全新异常,并将它们用于应用程序。

使用自定义异常有什么好处呢?为何要定义新异常类型?创建自定义异常是为了表示应用程序的一些错误类型,为代码可能发生的一个或多个问题提供新含义。可以显示代码多个位置之间的错误的相似性,也可区分代码运行时可能出现的相似问题的一个或多个错误,或给出应用程序中一组错误的特定含义。

例如,考虑任何类型的服务器。服务器的基本作用是处理与客户机的通信。若使用标准Java API(java.iojava.net包中的类)来编写服务器,则可使编写的代码在多个位置抛IOException 在设置服务器、等待客户机连接和获取通信流时,可抛出IOExceptions;在通信期间及试图断开连接时,也可抛出IOExceptions。简言之,服务器的各个部分都可能引发IOException

对服务器而言,这些IOException意义不尽相同。虽然由同一异常类型表示,但与各个异常相关的业务含义存在差异,报告和恢复操作亦有不同。可以将一个异常集与服务器配置和启动问题关联,将另一个异常集与客户机通信的实际行动关联,将第三个异常集与服务器关闭任务关联。使用自定义异常,可采用对应用程序有意义的方式来灵活地表示错误。

创建和使用自定义异常并不难。遵循以下3个步骤即可。

3.2.1  定义异常类

一般要定义新类来表示自定义异常。多数情况下,只需创建已有异常类的子类。

1  public class CustomerExistsException extends Exception{

2    public CustomerExistsException(){}

3    public CustomerExistsException(String message){

4      super(message);

5    }

6  }

至少要继承ThrowableThrowable的子类。经常需要定义一个或多个构造函数,以在对象中存储错误消息。如第2-4行所示。在继承任何异常时,将自动继承Throwable类的一些标准特性,如:

       错误消息

       栈跟踪

       异常包装

若要在异常中添加附加信息,则可以为类添加一些变量和方法:

1  public class CustomerExistsException extends Exception{

2    private String customerName;

3    public CustomerExistsException(){}

4     public CustomerExistsException(String message){

5       super(message);

6     }

7     public CustomerExistsException(String message, String customer){

8       super(message);

9       customerName = customer;

10     }

11     public String getCustomerName(){

12       return customerName;

13     }

14  }

由本例可知,可修改CustomerExistsException类,以支持其他属性。例如,可将customerName字符串(引发异常的记录的客户名)与异常联系起来。

3.2.2  声明方法抛出自定义异常

这实际上是“处理或声明”规则的“声明”部分。为了使用自定义异常,必须通知调用代码的类:要准备处理这个异常类型。为此,声明一个或多个方法抛出异常:

public void insertCustomer(Customer c) throws CustomerExistsException{

// The method stores customer information in the database.

// If the customer data already exists, the method creates

// and throws the CustomerExistsException.

}

3.2.3  找到故障点,新建异常并加上关键字throw

最后一步实际上是创建对象,并通过系统传送该对象。为此,需要了解代码将在方法的哪个位置出现故障。根据情况,可能要使用以下部分或所有条件,来指示代码中的故障点。

1. 外部问题

       应用程序中产生的异常

       其他方法返回的故障代码

2. 内部问题

       应用程序状态不一致

       应用程序中的处理问题

在本例中,当不能新建一个客户时会遇到一个故障场景。结果,创建一个异常来表示问题并抛出该问题。如下面的示例方法所示:

1  public void insertCustomer(Customer c)

2    throws CustomerExistsException, SQLException {

3    String selectSql =

4      "SELECT * FROM Customer WHERE first_name=? AND last_name=?";

5    String insertSql = "INSERT INTO Customer VALUES(?, ?)";

6    try{

7      Connection conn = dbmsConnectionFactory.getConnection();

8      PreparedStatement selStmt = conn.prepareStatement(selectSql);

9      selectStmt.setString(1, c.getFirstName());

10      selectStmt.setString(2, c.getLastName());

11      ResultSet rs = selStmt.executeQuery();

12      if (rs.next()){

13        // In this case, the failure condition is produced if you

14        //  can already locate a metching record in the database.

15       throw new CustomerExistsException("Customer exists:" + c, c);

16      }

17      else{

18        PreparedStatement insStmt = conn.prepareStatement(insertSql);

19        insStmt.setString(1, c.getFirstName());

20        insStmt.setString(2, c.getLastName());

21        int status = insStmt.executeUpdate();

22      }

23   }

24   catch (SQLException exc){

Java关键字throw将这个新异常对象传给该方法的调用者。在执行完这3个步骤后,就创建了自定义异常。除非派生一个非检测异常类(RuntimeExceptionError),否则调用方法的任何对象随后将按照“处理或声明”规则解决该异常。

这引出了一个有趣的问题:在自定义异常时,应如何派生?必须在Throwable类层次结构中派生,否则将不能在应用程序中传播异常。另外,不能从Throwable直接派生。Throwable为两类主要问题(ExceptionError)提供行为基础,不能为这棵继承树定义新分支。一般也不要直接继承Error或其任何子类,因为自定义异常通常不符合错误标准(即适当应用程序不应试图捕获的严重问题)

需要从Exception类层次结构中派生。一般地,应将自定义异常定义为故障状态更一般的异常类型的子类。例如,ServerConnectionExceptionjava.io.IOException的子类,因为Server- Connec tionExceptionjava.io.IOException的更具体类型。

如果定义的异常从RuntimeException树继承,是否属于正确的编码实践?若如此,就回避了异常机制,即使声明了异常,类也不必显式处理异常



自定义异常的原则(转)
       “本文是Exception处理的一篇不错的文章,从Java Exception的概念介绍起,依次讲解了Exception的类型(Checked/Unchecked),Exception处理的最佳实现:

1.  选择Checked还是Unchecked的几个经典依据

2.  Exception的封装问题

3.  如无必要不要创建自己得Exception

4.  不要用Exception来作流程控制

5.  不要轻易的忽略捕获的Exception

6.  不要简单地捕获顶层的Exception

——选自JAVADigest.Net对原文的介绍

只有注册用户登录后才能发表评论。