Java异常

在我参与过的一些Java项目、或者阅读过Java代码中,异常的使用或多或少都有点问题,有些甚至是误用。可能很多人都了解异常的基本知识,但是使用的时候往往过于随意,然而这样的随意往往并不能造成什么严重的问题,所以很多程序员,尤其是初级的程序员也就没有在意它,于是代码中总是会有那些让人不舒服的异常使用代码;另一方面,Java异常类型中包括Checked Exception(Runtime Exception)和Unchecked Exception,这两中异常的使用也颇具争议。
基于上述问题,总结一下Java异常基本知识点及常见错误,错漏之处欢迎批评指正。

异常的基本思想:首先是抛出异常,然后catch捕捉,但是catch得和try连用(try也可以仅和finally连用,无需catch的参与),catch捕捉的是try区中代码抛出的异常,一个 try可以跟多个catch,每个catch捕捉一种类型的异常,不确定异常时可用异常的super类,exception。异常的捕捉顺序按照catch的先后顺序。

1、Java异常结构

Java异常

所有的Java异常都是继承自Throwable。Throwable分为Error和Exception两大类,而程序员需要关注的是Exception这一部分的异常,Error不需要应用程序编程人员来使用的,按照《Java核心技术卷1》的定义:

Error类层次结构描述了Java运行时系统的内部错误和资源耗尽错误,应用程序不应该抛出这样的错误。

显然一旦这样的错误出现,程序除了终止别无他法。

2、Unchecked and Checked Exception

Error和Runtime Exception合称为Unchecked Exception,对应的另一类异常叫做Checked Exception。它们的区别在于后者编译时会被check,Java语言要求程序员必须捕获这样的异常(Checked Exception)或者沿着调用栈向上抛出,即在有可能抛出异常的方法体对应的方法名后加上throws specified-exception(例如throws exception)。常见的Checked异常包括IOException,例如用户的输入不符合要求、程序打开一个不存在的文件等。
另一类异常,Runtime Exception(Unchecked Exception),Java官方认为这样的异常其实是bug,这类异常应该是去解决而不是去捕获,所以Java不要求程序员捕获这类异常,但是程序员仍然可以去捕获这类的异常,这类异常包括空指针、数组访问越界等。
初学者可能会误认为文件读写异常或者用户输入异常是RuntimeException,其实不然,这里提醒一下。

3、自定义异常选择:Unchecked vs Checked

自定义异常选用Unchecked还是checked类型的一直以来就充满争议,而且其它语言也都只有RuntimeException,如C++。当然这些争议只存在于Java使用者之中,Java官方并不存在任何争议。
因为Java语言要求程序员必须捕获Checked Exception,于是很多程序员为了偷“不需要主动捕获异常”这个懒(当然也有很多程序员是出于设计的原因),将所有的自定义异常都继承自RuntimeException,这样就可以“想捕获就捕获,不想捕获就随它去了”。
我个人的观点是:遵循Java规范。原因有二:其一,定义Checked异常可以最大限度地借助IDE工具帮助我们规范代码,同时规范的代码也能告诉其他的代码调用者这段代码会抛出什么样的异常,也许有人会说,RuntimeException也可以在方法体上声明抛出何种异常,但是这样就不能最大限度的利用IDE或者编译器了,人总会有疲劳的时候,能让工具干的事情我们就不要插手了;其二,Java使用者甚多,遵循Java规范可能是唯一能让整个Java世界编程风格统一的方式了。

4、一个可能是Java编程史上最常见的异常使用错误

try {
    some codes;
}catch(Exception e){// 上来就直接使用异常的super类-Exception,可能程序并不会抛出任何异常或者仅仅是一个IOException
    some codes;
}

与其说是错误,不如说是使用不规范。(有没有随口而出,“我擦,我每天都是这么用的”)

5、异常小知识

1、捕获那些知道如何处理的异常,而将那些不知道如何处理的异常继续向上传递。
2、如果这是你编程造成的问题,那就是RuntimeException,反之亦然。
3、try不一定要与catch连用,也可以只接finally;但是try必须与catch或者finally中的一个或者全部一起使用。
4、finally块中尽可能地不要写return语句。
5、如果try块中有return语句,finally块会在try块的return语句return之前执行(假定try能执行到return语句)。
6、catch中捕获异常的顺序应遵循子类先catch的原则。

上一篇:基于css3新属性transform及原生js实现鼠标拖动3d立方体旋转


下一篇:移除首页->重回首页