这篇文章讲一下我对异常的一些看法,请各位看官多指教。
Exception分为两类:
checkedException:检查异常
uncheckedException:非检查异常
程序分两个阶段(不要太较真好吧),编译阶段和运行阶段,有些异常属于编译阶段,有些异常属于运行阶段,编译阶段的异常不加以处理是编译不过去的(程序跑不起来),运行阶段的异常不加以处理能编译能运行(程序能跑)。
根据以上内容,如果将checkedException和uncheckedException换俩名字我想就容易理解了,
checkedException:(针对于编译阶段来说)必须检查的异常
uncheckedException:(针对于编译阶段来说)不必须检查的异常
RuntimeException属于uncheckedException
我们还听说过一个说法:checkedException必须处理或者抛出uncheckedException可以不处理不抛出。
第一个我们理解,不处理抛出编译不过去,第二个是为什么呢?
为什么uncheckedException没有硬性要求呢?
我们先来举个属于uncheckedException的异常类ArrayIndexOutOfBoundException,数组角标越界异常。这样的例子还有很多。如果把运行时异常也必须处理抛出,那么程序会变得多么臃肿,异常满天飞。uncheckedException可处理可不处理的优势体现出来了,那就是如果异常都是必须捕获抛出的那么就会得不偿失。
总结一下:
为什么有些异常类是checkedException?
因为不捕获抛出就无法编译。
为什么有些异常类是uncheckedException?
因为这些异常对编译阶段无影响
为什么有些异常类可以捕获抛出也可以不捕获抛出?
因为有时候捕获抛出的收益小于捕获抛出的代价。
关于try catch finally 与return throw的那些事
先说一下try catch finally 与return之间的事
情况1:try{} catch(){}finally{} return;
显然程序按顺序执行。
情况2:try{ return; }catch(){} finally{} return;
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,最后执行try中return;
finally块之后的语句return,因为程序在try中已经return所以不再执行。(return可以起到跳出函数的作用)
情况3:try{ } catch(){return;} finally{} return;
程序先执行try,如果遇到异常执行catch块,
有异常:则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
最后执行catch块中return. finally之后也就是4处的代码不再执行。
无异常:执行完try再finally再return.
情况4:try{ return; }catch(){} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况5:try{} catch(){return;}finally{return;}
程序执行catch块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况6:try{ return;}catch(){return;} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
则再执行finally块,因为finally块中有return所以提前退出。
无异常:则再执行finally块,因为finally块中有return所以提前退出。
最终结论:任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
编译器把finally中的return实现为一个warning。
最先执行到的return代码的是有效的return
return返回值可以修改吗
简单点说java是值传递,比如:try{ a.name=zhangsan;return a;引用a;}catch(){;} finally{a.name=lisi;}
return的引用a的属性改变了。但是引用a是没有改变的。返回值不可修改!
我们看一下其他人的答案:
如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况,:
1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。
2)如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。
再说一下return与throw之间的事
程序中如果使用return的方式终止程序的执行,那么就不存在异常处理的问题了,此时不抛出异常直接用return的方式告诉调用者一个结果,这种情况下,调用者也不用处理异常了,根据返回的结果做相应的处理即可。
若直接抛出异常,在调用者势必会捕获着个 异常,那么此时的处理情况就不是拿返回值,而是针对这个抛出的异常做对应的处理了。
疑问在于在可以抛出异常和通过return的方式终止程序执行的适合,如何去选择是通过return还是throw的形式。
总结:return和throw都可以跳出函数,如果return跳出的函数那么异常信息就没有了,如果throw跳出的函数return就执行不到了。
参考资料:
http://blog.youkuaiyun.com/kavensu/article/details/8067850
http://blog.youkuaiyun.com/hguisu/article/details/6155636
https://www.zhihu.com/question/45715112