异常概述
java中Error和Exception都是继承与Throwable类,下图是异常层次图:
Error通常指程序运行时系统内部错误或者资源耗尽,应用程序是不应抛出这种对象。所以我们更加需要关注Exeption,由程序错误导致的异常属于Runtime Exception(Error异常可以认为是不可控制的,RuntimeExcetion应该避免发生的)IO错误导致的输入IOException,以下几种情况属于继承于RuntimeException的异常:
- 错误的类型转换
- 数组访问越界
- 访问空指针
而不是继承于RuntimeException的异常包括:在文件尾部后面读取数据,打开错误格式URL,调用Class.forName但是传入一个不存在的class name。所以说如果出现属于RuntimeException,那么一定是使用者使用不当造成的,比如检查一下空指针,数组越界问题等。
Java语言规范中将继承于Error类或者RuntimeException类的异常都称为unchecked exception
,所有其它的异常称为checked exception
在处理可能会发生checked exception时要在首部声明所有可能抛出的异常,例如FileInputStream的构造器
|
|
当有异常发生时,构造器将抛出一个FileNotFoundException对象。
以下四种情况程序可能抛出异常:
- 调用了可能抛出已检查异常的方法:例如FileInputStream构造器
- 检测到了错误,然后使用
throw
关键字抛出一个已检查异常 - 程序出现错误,比如数组越界,抛出一个未检查异常
- jvm或者运行库的内部错误
对于那些可能被他人使用的java方法,应该根据异常规范在方法的首部声明方法可能抛出的异常,如有多个已检查异常,必须在方法的首部列出的异常类,但是不需要声明继承Error或者RuntimeException的类。总之,方法必须声明所有可能抛出的已检查的异常。
除了声明异常之外还可以捕获异常,这样能使的异常不会抛出方法之外,也不需要throws
> 子类如果覆盖了超类的方法,子类方法声明的已检查异常不能超过超类的声明异常范围
类中方法声明抛出一个异常类A,但实际上可以抛出异常类B,B是A的子类
抛出异常
利用try-catch捕捉异常:
|
|
当然如果try子句中抛出了没有声明的异常类型,那么方法立刻退出
finally关键字
如果代码抛出一个异常,就会终止方法中剩余代码,如果之前打开了本地资源,那么资源在方法推出之前被回收,那么就会产生资源回收问题。一种解决方案捕捉将异常抛给上层,这样就要在正常和异常部分的代码分别回收资源。
finally子句是一种更加优雅的方法,不管是否有异常捕获finally子句代码都被执行,当finally含有return子句
|
|
如果调用f(2),会返回0