while((child = getNestedException(parent)) != null) {
if (child != null) {
w.print("Caused by: ");
child.printStackTrace(w);
if (child instanceof ApplicationException) {
break;
}
parent = child;
}
}
}
public Throwable getCause() {
return cause;
}
}
清单 1 中的代码很简单;我们已经简单地将多个异常“串”在一起,以创建单个、嵌套的异常。但是,真正的好处在于将这种技术作为出发点,以创建特定于应用程序的异常层次结构。异常层次结构将允许 EJB 客户机既接收特定于业务的异常也接收特定于系统的信息,而不需要编写大量额外代码。
异常层次结构
异常层次结构应该从一些十分健壮而又通用的异常入手,如 ApplicationException。如果您将顶级异常搞得太具体,那么其结果是您今后将不得不重新构造层次结构,以适应某些较通用的情况。
因此,让我们假定您的应用程序要求 NoSuchBookException、InsufficientFundsException 和 SystemUnavailableException。您不必创建这三个异常,让它们继承 ApplicationException,然后只需提供极少几个必须的构造器来创建格式化的消息。清单 2 是此类异常层次结构的示例:
清单 2. 异常层次结构 package com.ibm.library;
import com.ibm.ApplicationException;
public class NoSuchBookException extends ApplicationException {
public NoSuchBookException(String bookName, String libraryName) {
super("The book " + bookName + " was not found in the " +
libraryName + " library.");
}
}
当需要编写大量专用异常时,异常层次结构极大地简化了工作。对于一个异常,为每个异常类添加一个或两个构造器,所花费时间很少不超过几分钟。您还经常需要给这些更具体的异常(这些异常也是主应用程序异常的子类)提供子类,以提供更具体的异常。例如,您可能需要 InvalidTitleException 和 BackorderedException 来继承 NoSuchBookException。
企业应用程序在构建时通常都不会注意异常处理。尽管依靠低级异常(如 RemoteException 和 NamingException)很容易(有时也很诱人),但如果一开始就建立一个可靠的、深思熟虑的异常模型,则您将在应用程序上少花很多精力。创建一个嵌套的、层次结构化的异常框架将改进代码的可读性及其可用性。