许多种类的错误将触发异常,这些问题从像硬盘(crash)坠毁这样的严重硬件错误,到尝试访问越界数组元素这样的简单程序错误,像这样的错误如果在java函数中发生,函数将创建一个异常对象并把他抛出到运行时系统(runtimesystem)。
许多种类的错误将触发异常,这些问题从像硬盘(crash)坠毁这样的严重硬件错误,到尝试访问越界数组元素这样的简单程序错误,像这样的错误如果在java函数中发生,函数将创建一个异常对象并把他抛出到运行时系统(runtimesystem)。异常对象包含异常的信息,包括异常的类型,异常发生时程序的状态。运行时系统则有责任找到一些代码处理这个错误。在java技术词典中,创建一个异常对象并把它抛给运行时系统叫做:抛出异常(throwinganexception)。
当某个函数抛出一个异常后,运行时系统跳入了这样一个动作,就是找到一些人(译者注:其实是代码)来处理这个异常。要找的处理异常的可能的人(代码)的集合(set)是:在发生异常的方法的调用堆栈(callstack)中的方法的集合(set)。运行时系统向后搜寻调用堆栈,从错误发生的函数,一直到找到一个包括合适的异常处理器(exceptionhandler)的函数。一个异常处理器是否合适取决于抛出的异常是否和异常处理器处理的异常是同一种类型。因而异常向后寻找整个调用堆栈,直到一个合格的异常处理器被找到,调用函数处理这个异常。异常处理器的选择被叫做:捕获异常(catchtheexception)。
如果运行时系统搜寻整个调用堆栈都没有找到合适的异常处理器,运行时系统将结束,随之java程序也将结束。
使用异常来管理错误,比传统的错误管理技术有如下优势:
1. 将错误处理代码于正常的代码分开。
2. 沿着调用堆栈向上传递错误。
3. 将错误分作,并区分错误类型。
1. 将错误处理代码于正常的代码分开。
在传统的程序种,错误侦测,报告,和处理,经常导致令人迷惑的意大利面条式(spaghetti)的代码。例如,假设你要写一个将这个文件读到内存种的函数,用伪代码描述,你的函数应该是这个样子的:
readFile
open the file; //打开文件
determine its size; //取得文件的大小
allocate that much memory; //分配内存
read the file into memory; //读文件内容到内存中
close the file; //关闭文件
匆匆一看,这个版本是足够的简单,但是它忽略了所有潜在的问题:
n 文件不能打开将发生什么?
n 文件大小不能取得将发生什么?
n 没有足够的内存分配将发生什么?
n 读取失败将发生什么?
n 文件不能关闭将发生什么?
为了在read_file函数中回答这些错误,你不得不加大量的代码进行错误侦测,报告和处理,你的函数最后将看起来像这个样子:
errorCodeType readFile
initialize errorCode = 0;
open the file;
if (theFileIsOpen)
determine the length of the file;
if (gotTheFileLength)
allocate that much memory;
if (gotEnoughMemory)
read the file into memory;
if (readFailed)
errorCode = -1;
else
errorCode = -2;
else
errorCode = -3;
close the file;
if (theFileDidntClose && errorCode 0)
errorCode = -4;
else
errorCode = errorCode and -4;
else
errorCode = -5;
return errorCode;
随着错误侦测的建立,你的最初的7行代码(粗体)已经迅速的膨胀到了29行-几乎400%的膨胀率。更糟糕的是有这样的错误侦测,报告和错误返回值,使得最初有意义的7行代码淹没在混乱之中,代码的逻辑流程也被淹没。很难回答代码是否做的正确的事情:如果函数分配内容失败,文件真的将被关闭吗?更难确定当你在三个月后再次修改代码,它是否还能够正确的执行。许多程序员“解决”这个问题的方法是简单的忽略它,那样错误将以死机来报告自己。
对于错误管理,Java提供一种优雅的解决方案:异常。异常可以使你代码中的主流程和处理异常情况的代码分开。如果你用异常代替传统的错误管理技术,readFile函数将像这个样子:
readFile
try
open the file;
determine its size;
allocate that much memory;
read the file into memory;
close the file;
catch (fileOpenFailed)
doSomething;
catch (sizeDeterminationFailed)
doSomething;
catch (memoryAllocationFailed)
doSomething;
catch (readFailed)
doSomething;
catch (fileCloseFailed)
doSomething;
注意:异常并不能节省你侦测,报告和处理错误的努力。异常提供给你的是:当一些不正常的事情发生时,将所有蹩脚(grungy)的细节,从你的程序主逻辑流程中分开。
另外,异常错误管理的膨胀系数大概是250%,比传统的错误处理技术的400%少的多。
tags:异常
posted on 2009-06-25 23:45
jadmin 阅读(73)
评论(0) 编辑 收藏