前几天老师讲了异常,之前也接触过,可是一直没把它放在心上,自然也没学好。现在回头来看看,发现它真的很有用。
为什么要有异常,它的作用是什么,怎么用?
永远不要指望你的程序不会出现错误,既然有错误,那就必须要处理,所以就有了异常。
异常:
什么出错了
哪里出错了
为什么出错
java中的异常机制包括Error和Exception两个部分。他们都继承自一个共同的基类Throwable。Error属于JVM运行中发生的一些错误,虽然并不属于开发人员的范畴,但是有些Error还是由代码引起的,比如StackOverflowError经常由递归操作引起,这种错误就是告诉开发者,你一般无法挽救,只能靠JVM。而Exception假设程序员会去处理这些异常,比如数据库连接出了异常,那么我们可以处理这个异常,并且重新连接等。Exception分为两种,检查类型(checked)和未检查类型(unchecked)。检查类型的异常就是说要程序员明确的去声明或者用try..catch语句来处理的异常,而非检查类型的异常则没有这些限制,比如我们常见的 NullPointerException 就是非检查类型的,他继承RuntimeException。java是目前主流编程语言中唯一一个推崇使用检查类型异常的,至少sun是这样的。
try{
//可能出现异常的语句
}
catch(ExceptionType1 e) {
//处理捕获的异常
} catch(ExceptionType2 e) {
//处理捕获的异常
} catch(Exception e) {
//处理捕获的异常
}
finally{
//do something …比如说关闭一些流什么的
}
这里要注意的是,在Catch里,要把catch (Exception e)写在最后,先匹配子类,然后匹配父类。
一旦某个catch得到匹配后,其他的就不会就匹配了,有点像加了break的case。
好的原则
Fail Fast:就是要尽早的抛出异常,这样有有助于更加精确的定位出错的地点和原因。这个也比较好理解,比如用户名字不合法的时候马上抛出,UserNameIllegalException,如果没有及时抛出异常,那么不合法的名字可能会导致一个SQLException,但是程序报给你一个SQLException,你却很难直接得知一定是用户名不合法造成的。Fail Fast这种思想,在java实现ArrayList的机制中也有很好的体现。
Catch late:不要在方法内部过早的处理异常,特别是什么也不做的处理,那就更加的可怕了。因为如果“无作为”的处理很可能导致后面继续出现新的异常(比如错误的用户名会引发后面一些列错误,程序还不能处理好错误的用户名,后面的就更处理不了了),这就给调试增加了很大的困难。一个好的经验是将异常处理交给调用者,方法只在及时的地方抛出异常,技术上实现的方式就是给方法声明throws,标出所有可能要抛出的异常。
Doc:文档的重要性,特别是非检查的异常,一定要在文档中注明。
异常处理是java非常重要的特性,上面是一些关于异常使用的讨论,当然更多知识还是需要实践中发现。(后部分内容为转载)