Java核心技术学习笔记(三)

1.在Java程序设计语言中,异常对象都是派生于Throwable类的一个实例。在Throwable的下一层分解为两个分支:Error和Exception。

Error类层次结构描述了Java运行时系统的内部错误和资源耗尽错误。应用程序不应该抛出这种类型的对象。如果出现了这样的内部错误,除了通告给用户,并尽力使程序安全地终止之外,再也无能为力了。这种情况很少出现。

设计Java程序时,需要关注Exception层次结构。这个层次结构又分解为两个分支:一个分支派生于RuntimeException;另一个分支包含其他异常。划分两个分支的规则是:由程序错误导致的异常属于RuntimeException;而程序本身没有问题,但由于像I/O错误这类问题导致的异常属于其他异常。

派生于RuntimeException的异常包含以下几个情况:

(1)错误的类型转换

(2)数组访问越界

(3)访问空指针

不是派生于RuntimeException的异常包括:

(1)试图在文件尾部读取数据

(2)试图打开一个错误格式的URL

(3)试图根据给定的字符串查找Class对象,而这个字符串表示的类并不存在

如果出现RuntimeException异常,那么就一定是程序员的问题。

Java语言规范将派生于Error类或RunTimeException类的所有异常称为未检查(unchecked)异常,所有其他的异常称为已检查(checked)异常。

一个方法必须声明所有可能抛出的已检查异常,而未检查异常要么不可控制(Error),要么就应该避免发生(RuntimeException)。如果方法没有声明所有可能发生的已检查异常,编译器就会给出一个错误消息。


2.如果在子类中覆盖了超类的一个方法,子类方法中声明的已检查异常不能超过超类方法中声明的异常范围。特别需要说明的是,如果超类方法没用抛出任何已检查异常,子类也不能抛出任何已检查异常。


3.在C++和Java中,抛出异常的过程基本相同,只有一点微小的差别。在Java中只能抛出Throwable子类的对象,而在C++中,却可以抛出任何类型的值。


4.为了让用户抛出子系统中的高级异常,而不会丢失原始异常的细节,可以使用如下包装技术:

try

{

XXXXXX

}

catch(Exception e)

{

Throwable mye = new MyException("my info");

mye.initCause(e);

throw mye;

}

当捕获到异常时,就可以使用下面这条语句重新得到原始异常:

Throwable e = mye.getCause();


5.在JavaSE5.0中,增加了一个静态的Thread.getAllStackTrace方法,它可以产生所有线程的堆栈跟踪。方法的具体实现方式如下:

Map<Thread,StackTraceElement[]> map = Thread.getAllStackTraces();

for(Thread t:map.keySet())

{

StackElement[] frames = map.get(t);

分析 frames

}


6.使用断言的建议:

断言失败是致命的,不可恢复的错误

断言检查只用于开发和测试阶段

因此,不应该使用断言向程序的其他部分通告发生了可恢复性的错误,或者,不应该作为程序向用户通告问题的手段。断言只应该用于在测试阶段确定程序内部的错误位置。





你可能感兴趣的:(java)