Java使用一种称为异常处理的错误捕获机制处理。
一、处理错误
错误包含:
1、用户输入错误。
2、设备错误。
3、物理限制。
4、代码错误。
在Java程序设计语言中,异常对象都是派生于Throwable类的一个实例。
Throwable有两个分支:Error和Exception。
Error类层次结构描述了Java运行时系统的内部错误和资源耗尽错误。
Exception类层次分解为两个分支:一个分支派生于RuntimeException;另一个分支包含其他异常。划分两个分支的规则是:由程序错误导致的异常属于RuntimeException;而程序本身没有问题,但由于像I/O错误这类问题导致的异常属于其他异常。
派生于RuntimeException的异常包含下面几种情况:
1、错误的类型转换。
2、数组访问越界。
3、访问null指针。
不是派生于RuntimeException的异常包括:
1、试图在文件尾部后面读取数据。
2、试图打开一个不存在的文件。
3、试图根据指定的字符串查找Class对象,而这个字符串表示的类并不存在。
Java语言规范将派生于Error类或RuntimeException类的所有异常称为非受查异常;所有其他的异常称为受查异常。
遇到下面四种情况时应该抛出异常:
1、调用一个抛出受查异常的方法。
2、程序运行过程中发现错误,并且利用throw语句抛出一个受查异常。
3、程序出现错误。
4、Java虚拟机和运行时库出现的内部错误。
二、捕获异常
Java通常采用try...catch用来捕获异常,语法格式:
try{ code } catch(Exception e){ handler for this type }
不管是否有异常被捕获,finally子句中的代码都会被执行。
堆栈轨迹是一个方法调用过程的列表,它包含了程序执行过程中方法调用的特定位置。可以使用Throwable类的printStackTrace方法访问堆栈轨迹的文本描述信息;也可以使用getStackTrace方法,它会的啊StackTraceElement对象的一个数组,StackTraceElement类中含有能够获得文件名和当前执行的代码行号的方法,同时,也含有能够获得类名和方法名的方法。
三、使用异常机制的技巧
1、异常处理不能代替简单的测试。只在异常情况下使用异常机制。
2、不要过分的细化异常。将正常处理和错误处理分开。
3、利用异常层次结构。
4、不要压制异常。
5、在检测错误时,“苛刻”要比放任更好。
6、不要羞于传递异常。
四、断言
断言机制允许在测试期间向代码中插入一些检查语句。
Java语言隐入了关键字assert。
断言的表现形式:
1、assert条件;
2、assert条件:表达式;
这两种形式都会对条件进行检测,如果结果为false,则抛出一个AssertionError异常。在第二种形式中,表达式将被传入AssertionError的构造器,并转换成一个消息字符串。
可以在程序中使用-enableassertions或-ea启用断言;使用-disableassertions或-da禁用某个特定类和包的断言;启用和禁用断言是类加载器的功能。
Java语言中,给出三种处理系统错误的机制:
1、抛出一个异常。
2、日志。
3、使用断言。
什么时候使用断言:
1、断言失败是致命的,不可恢复的错误。
2、断言检查只用用于开发和测试阶段。
断言是一种测试和调试阶段所使用的战术性工具;而日志记录是一种在程序的整个生命周期都可以使用的策略性工具。
五、记录日志
通常,有以下七个日志记录器级别:
SEVERE;WARNING;INFO;CONFIG;FINE;FINER;FINEST
在默认情况下,只记录前三个级别。
六、调试技巧
1、打印或记录任意变量的值。
2、在每一个类中放置一个单独的main方法,这样就可以对每一个类进行单元测试。
3、使用JUnit单元测试框架。
4、日志代理是一个子类的对象,它可以截获方法调用,并进行日志记录,然后调用超类中的方法。
5、利用Throwable类提供的printStackTrace方法,可以从任何一个异常对象中获得堆栈情况。
6、一般来说,堆栈轨迹显示在System.err上。
7、要想观察类的加载过程,可以用-verbose标志启动Java虚拟机。
8、-Xlint选项告诉编译器对一些普通容易出现的代码问题进行检查。
9、Java虚拟机增加了对Java应用程序进行监控和管理的支持。
10、可以使用jmap实用工具获得一个堆的转储,其中显示了堆中的每个对象。
11、如果使用-Xprof标志运行Java虚拟机,就会运行一个基本的剖析器来跟踪那些代码中经常被调用的方法。