首先,链接几篇有用的博文
http://blog.csdn.net/hguisu/article/details/6155636#comments
http://lavasoft.blog.51cto.com/62575/18920
Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。
在Java中,每个异常都是一个对象,它是Throwable类或它的子类Exception(异常)
和 Error(错误)的实例。当一个方法出现异常后便抛出一个异常对象,
该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。
Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。
用try来指定一块预防所有”异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的”异常”的类型。
throw语句用来明确地抛出一个”异常”。throws用来标明一个成员函数可能抛出的各种”异常”。
Finally为确保一段代码不管发生什么”异常”都被执行一段代码。
可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,
“异常”的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种”异常”进行处理,堆栈就会展开,
直到遇到有处理这种”异常”的try语句。
如果Java的内置异常不满足需求,则可以创建自定义异常。这样就必须从已有的异常类继承。
Error类描述了Java运行时系统的内部错误和资源耗尽错误,此类错误不应由应用程序抛出。
而Exception分两类,一类是因程序逻辑问题,导致系统出问题,此时就是Runtime异常,如数组越界、类型转换错误、访问空指针。
而如果程序可以正常,但在遇到不同IO情况时,出问题导致,则属于IO异常,如打开格式错误的URL、在文件尾部读数据、加载不存在的类文件等。
RuntimeException一定是程序写的有问题,是可以避免出现的。
Java将Error和RuntimeException定义为未检查的异常。其他异常为已检查的异常。编译器将检查代码是否为所有已检查异常提供异常处理器。
栈轨迹是通过getStackTrace()方法来返回一个数组,数组里的元素是从抛出异常处到第一个被调用的方法处。
垃圾回收器会自动清理掉异常对象
Throws抛出异常的规则:
1) 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。
2)必须声明方法可抛出的任何可查异常(checked exception)。即如果一个方法可能出现受可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误
3)仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣。
catch块
如果try语句中的任何代码抛出一个在catch中指定的异常,则程序会跳过try语句中的其余代码转而执行catch子句中的代码。
如果抛出的是不在catch中指定的异常,则程序立即返回到上层调用者。
catch()括号中的异常可以匹配它和它的所有子类。
如果异常被前面的coach语句捕获并且处理,那么后面的catch语句将被屏蔽。
所以遵循捕获的异常先子类后基类。不然编译器会报错
finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。
丢失异常:
finally子句中的方法抛出了异常,就会把catch到的异常换成finally子句产生的异常。
从finally子句中return,就会不产生异常的输出
异常的限制:如图
构造器:
在构造器内产生的异常怎么办?
对于在构造阶段可能会抛出异常,并且要求清理的类,最安全的方式是使用嵌套的try语句。
try{
构造对象
try{
}
catch(Exception e){
}
finally{
}
}catch(Exception e){
}