java异常结构以及作用

Throwable类:所有的异常类,都直接或者间接的继承这个类。三个重要的方法:


堆栈跟踪是方法调用过程的轨迹,它包含了程序执行过程中方法调用的顺序和所在源代码行号。

堆栈跟踪信息从下往上,是方法调用的顺序。

Throwable类的两个直接子类:

Error:是程序无法修复的严重问题,程序员无法修复,这能让程序终止,比如jvm内部错误、存溢出和资源耗尽等严重情况。

Exception:是程序可以恢复的程序,是程序员可以从掌控的,比如,除零异常,空指针访问,网络连接终端,读取不存在等。


在Exception下面又有两个异常:

    非受检异常指的是java.lang.RuntimeException和java.lang.Error类及其子类,所有其他的异常类都称为受检异常。两种类型的异常在作用上并没有差别,唯一的差别就在于使用受检异常时的合法性要在编译时刻由编译器来检查。正因为如此,受检异常在使用的时候需要比非受检异常更多的代码来避免编译错误。

1 受检查异常:指除RuntimeException以外的异常类。共同特点是,编译器会检查这类异常是否进行了处理,要么捕获,要么不抛出,否则会发生编译错误,种类很多。

2 非受检查异常(运行时异常):运行时异常是继承RuntimeException类的直接子类或者间接子类,运行时异常往往是程序员所犯的错误导致的 。特点是编译器不检查这类异常是否得到了处理,对于这类异常不捕获也不抛出,程序也可以编译过,一旦遇到就导致程序终止。

    对于运行时异常通常不采用抛出或捕获处理方式,而是应该提前预判,防止这种发生异常,做到未雨绸缪。例如除零时候,在进行除法运算之前应该判断除数是非零的,修改示例代码如下,从代码可见提前预判这样处理要比通过try-catch捕获异常要友好的多。


捕获异常:


try代码块中应该包含执行过程中可能会发生异常的语句。

     每个try代码块可以伴随一个或多个catch代码块,用于处理try代码块中所可能发生的多种异常。catch(Throwable e)语句中的e是捕获异常对象,e必须是Throwable的子类,异常对象e的作用域在该catch代码块中。


上图中,try是可能发生异常的语句,如果发生异常,catch来抓住,catch中的类跟对象,是catch要捕获的try监测语句可能发生的异常所属于的父类或者直接类。然后e对象存储,{  e.object}里面e调用类的方法,显示要捕获的信息。在捕获到异常之后,通过e.printStackTrace()语句打印异常堆栈跟踪信息,往往只是用于调试,给程序员提示信息。堆栈跟踪信息对最终用户是没有意义的。


多catch时候:

如果try代码块中有很多语句会发生异常,而且发生的异常种类又很多。那么可以在try后面跟有多个catch代码块

在多catch情况下,当一个catch捕获到异常时候,后面的catch就不在匹配。当捕获的多个异常类之间存在父子关系时,捕获异常顺序与catch代码块的顺序有关。一般先捕获子类,后捕获父类,否则子类捕获不到。也就是说,我们在排布catch时候是有顺序的,继承关系的异常,子类异常在前,父类在后,不同继承的异常,则不用关心顺序。

    释放资源:

有时在try-catch语句中会占用一些非Java资源,如:打开文件、网络连接、打开数据库连接和使用数据结果集等,这些资源并非Java资源,不能通过JVM的垃圾收集器回收,需要程序员释放。为了确保这些资源能够被释放可以使用finally代码块或Java7之后提供自动资源管理(AutomaticResource Management)技术。

finally代码块:


无论try正常结束还是catch异常结束都会执行finally代码块。



自动化管理技术:


实例代码:


上述代码第①行~③行是声明或初始化三个输入流,三条语句放到在try语句后面小括号中,语句之间用分号;”分隔,这就是自动资源管理技术了,采用了自动资源管理后不再需要finally代码块,不需要自己close这些资源,释放过程交给了JVM

所有可以自动管理的资源需要实现AutoCloseable接口,上述代码中三个输入流FileInputStream、InputStreamReader和BufferedReader从Java 7之后实现AutoCloseable接口,具体哪些资源实现AutoCloseable接口需要查询API文档。


在一个方法中如果能够处理异常,则需要捕获并处理。但是本方法没有能力处理该异常,捕获它没有任何意义,则需要在方法后面声明抛出该异常,通知上层调用者该方法有可以发生异常。方法后面声明抛出使用throws关键字

如果声明抛出的多个异常类之间有父子关系,可以只声明抛出父类。但如果没有父子关系情况下,最好明确声明抛出每一个异常,因为上层调用者会根据这些异常信息进行相应的处理。假如一个方法中有可能抛出IOException和ParseException两个异常,那么声明抛出IOException和ParseException呢?还是只声明抛出Exception呢?因为Exception是IOException和ParseException的父类,只声明抛出Exception从语法是允许的,但是声明抛出IOException和ParseException更好一些。

比如在main方法:


main中引用的readDate()方法:



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值