Java核心基础之容易被忽视的细节问题——异常处理

来源:互联网 发布:金融数据挖掘 pdf 编辑:程序博客网 时间:2024/06/06 14:05

1、在try块中声明的变量是局部变量,在catch、finally、以及异常处理外都不能被访问。所以我们要把InputStream/OutputStream一类的变量声明在try块外,以方便在finally块中关闭连接。

2、当try块中出现异常时,JVM会生成一个类型最合适的异常对象记录异常信息,再通过instanceof关键字与catch块声明的异常类型逐个比较寻求捕获。如果异常没有被捕获,就抛出异常,程序停止运行。

3、进行异常捕获时要先捕获小异常,再捕获大异常,即先捕获子异常类再捕获父异常类。

4、Java7中定义可在一个catch中捕获多种异常,形如:
try{……;}catch(IndexOutOfBoundsException | NumberFormatException ex){……;}

但是请注意,当使用捕获多异常时,ex变量就被隐式声明为final类型,不能被修改;而捕获单异常时,异常变量就不是final类型,可以被修改。

5、finally块只有在以下情况不会执行:
(1)在try块或catch块中调用System.exit(1);
(2)CPU出现异常被关闭;
(3)执行finally块所在线程阻塞或死亡;
(4)finally块中抛出异常并未被捕获,则finally块不会被执行完毕。

6、try-catch-finally的return问题
当try块中return的时候,
a、要么在catch块中return;
b、要么在异常处理外return;
c、要么在finally块中return;
为保证捕获异常后也能有返回值返回,a、b、c三种情况至少存在一种,否则编译出错。且a、b两种情况不能同时存在,效果相同,都是在捕获异常后return。当情况c存在时,其他的返回值均失效,一定返回finally块中的返回值。

7、throws与throw区别
throws是声明抛出异常,由JVM去自动处理异常,打印异常栈信息,终止程序运行。需要注意的是,throws只能写在方法签名之后,且子类只能声明抛出比父类范围相等或更小的异常(即子异常类)。
throw是主动抛出异常的方式,更加灵活。需要注意的是,当显示抛出异常时,要么需要try-catch处理,要么需要throws显式声明抛出异常。

8、Check异常与Runtime异常区别
Check异常是编译期会检查的异常,必须捕获或声明抛出才能通过编译,体现了Java的设计思想,要求严谨性,但许多Check异常我们只是显式的抛出并不知道如何处理。
Runtime异常在编译期不会被检查,但是仍然可以通过try-catch捕获,所以具有更大的灵活性。

9、项目中如何正确使用异常
(1)使用try-catch-finally结构捕获相关异常。
(2)在catch中捕获相关异常,将相关异常信息提供给管理员,并throw适应用户的自定义异常。
示例如下:
//自定义异常类,如果想要自定义运行时异常,请继承RuntimeException类public class MyException extends Exception{/** *  */private static final long serialVersionUID = 1L;public MyException(){}public MyException(String msg){super(msg);}}
//场景测试类public class ActionTest {//初始值private double initPrice = 30.0;//竞价方法,提出竞价public void bid(String bidPrice) throws MyException{double d = 0.0;try{d = Double.parseDouble(bidPrice);}catch(Exception ex){ex.printStackTrace();throw new MyException("竞价必须数值,不能包含其它字符!");}if(d <= initPrice){throw new MyException("竞价必须大于初始值!");}initPrice = d;}//测试public static void main(String[] args){ActionTest action = new ActionTest();try {action.bid("abc");} catch (MyException e) {System.err.println(e.getMessage());}}}


这样就向用户屏蔽了底层异常。

其他方面:
(1)不依赖异常,一些完全可以预知且处理逻辑清晰的错误尽量不使用异常处理。
(2)捕获异常后要进行对应的处理,而不仅仅是输出异常信息。
(3)try块要尽力精简。
1 0