根据《Java核心技术》整理
异常体系
1、Java所有的异常都派生于Throwable
,并且在Throwable
下面派生出Error
类和Exception
,Error一般是运行时系统内部错误以及资源耗尽,一般很少出现,重点关注Exception,它又分解成两个分支:IOException
和RuntimeException
RuntimeException通常包括以下几个方面:
-
错误的类型转换
-
数组越界访问
-
访问null指针
可以看出基本上都是程序逻辑上的错误
而一般I/O异常包括
-
试图在文件末尾读取数据
-
试图打开一个不存在的文件
-
试图根据给定的字符串查找Class对象,而这个字符串表示的类并不存在
java的异常体系如图所示
**如果出现RuntimeException异常,那么就一定是你的问题!**很好理解,你自己定义的数组不能自己都访问不了吧,你有没有对象应该自己清楚,你定义的是什么类型,能不能转换这些都是本来应该由程序员自己判断的事总不能都交给虚拟机吧。虽然你错了虚拟机还是会抛出异常,但这就属于程序员自己的问题了
2、派生于Error
类或RuntimeException
类的异常成为非受查异常(顾名思义,不需要检查的,因为Error
类是系统内部错误,不可能提前检查出来,而RuntimeException
是程序员自己应该管理的),其他异常称为受查异常
3、抛出异常使用声明情形
-
调用一个抛出受查异常的方法
-
程序运行过程中发现错误,并且利用throw语句抛出一个受查异常
-
程序出现错误
-
Java虚拟机和运行时库出现的内部错误
避免RuntimeException
不需要声明Java的内部错误,因为任何程序都可能抛出这种异常,也不需要声明RuntimeException
异常,这种异常应该由程序员避免
抛出所有受查异常
一个方法必须声明所有可能抛出的受查异常,因为非受查异常要么是不可控制(Error
),要么就是应该避免的(RuntimeException
),如果方法没有声明所有可能发生的受查异常,编译器就会发出一个错误信息
子类覆盖父类的方法
子类如果覆盖父类的方法,那么子类声明的异常范围不能比父类大,子类可以抛出更特定的异常,或者不抛出异常。如果父类没有抛出异常,子类也不应该抛出异常
更多情况
如果一个方法声明的异常是某个类的实例时,那么既有可能抛出这个类的异常,也有可能抛出这个子类的异常,比如IOException
,既有可能抛出IOException
,也有可能抛出它的子类异常如FileNotFoundException
如果方法中使用了throws
抛出异常,那么在调用这个方法的时候就必须捕获这个异常,或者继续抛出,否则会编译错误