background image

  好异常处理提供了处理程序错误的统一机制。事实上,Java 语言通过向调用者提出异
常警告的方式而显著地提升了软件开发中的异常处理能力。这种方式把 Java

语言中的 方

法(method)”进行了扩展和增强,使之包括了自身的错误条件。下面就让我们看一个例子,
这个例子说明了这种情况。
  以下是 FileInputStream 构造器之一的原型:
  

public

 FileInputStream(String name) 

throws

 FileNotFoundException Java

  的方法和构造器必须声明他们在被调用时可能 扔出 的异常,采用的关键字就是

throws

”。这种在方法原型中出现的异常提示增加了编程的可靠性。

  显而易见,这种方式是向方法的调用者提示了可能出现的异常条件,这样调用者就
可以对这些异常作出适当的相应处理。以下代码示意我们是如何捕获并且处理
FileNotFoundException 这一异常的:
  

1234567891011

  

try

  {
  FileInputStream fis = 

new

 FileInputStream(args[

0

]);

  

// other code here ...

 
  }
  

catch

 (FileNotFoundException fnfe)

  {
  System.out.println("File: " + args[

0

] + " not found. Aborting.");

  System.exit(

1

);

  }
 
  Java 异常处理还有其他一些优秀的特性,这就是可检查异常、用户定义异常和在 JDK 

1.4

中推出的新型 Java 记录 API(Java Logging API)。java.lang.Exception 的所有子类都属于可

检查异常。可检查异常(checked exception)是扔出该异常的方法所必须提示的异常,这种异
常必须被捕获或者向调用者提示。用户定义异常(User-defined exceptions)是定制的异常类,
这种异常类扩展了 java.lang.Exception 类。优良的 Java 程序规定定制异常封装、报告和处理
他们自己独有的情况。最新的 Java 记录 API(logging API)则可以集中记录异常。
  不好的 Java 异常处理
  不好的一面包括两种情况:滥用不可检查异常(unchecked exceptions)和滥用 catchall
构造器等。这两种方式都使得问题变得复杂起来。
  有一种类别的异常属于 RuntimeException 的子类,这种异常不会受到编译器的检查。
比如,NullPointerException

 

和 ArrayStoreException 就是这种类型异常的实例。程序员可以

对 RuntimeException 进行子类化以回避检查异常的限制,从而便于产生这些异常的方法
为其调用者所使用。
  专业的开发团队应当只允许在很少的情况下才可以这样做。
  第二种异常处理的陋习是 catchall

构造器。所谓的 catchall 

构造器 就是一种异常捕获

代码模块,它可以处理所有扔给它的可能异常。
  以下是 catchall 处理器的实例:
  

123456789

  

try

  {