前面我们学习了面向对象处理异常的两种方式,一个是抛出异常,一个是捕捉异常。但是在异常处理当中还有一个关键字我们没有讲到,就是finally关键字。这个关键字的作用是在其后的关键字无论是什么都会被执行到。比如我们先来看一个例子:
1 class DemoE3 2 { 3 4 int [] arr = {2,3,4,5}; 5 int index = 0; 6 7 DemoE3(int index) 8 { 9 10 this.index = index; 11 12 } 13 14 void method() 15 { 16 17 try 18 { 19 20 System.out.println("The Five element is "+ arr[index]); 21 22 }catch(IndexOutOfBoundsException e) 23 { 24 25 System.out.println("The index out of bouns"); 26 27 }finally 28 { 29 30 System.out.println("Array operation done"); 31 32 } 33 34 System.out.println("over"); 35 36 } 37 38 } 39 40 class ExceptionDemo3 41 { 42 43 public static void main(String[] args) { 44 45 DemoE3 d1 = new DemoE3(2); 46 d1.method(); 47 DemoE3 d2 = new DemoE3(6); 48 d2.method(); 49 50 } 51 52 }
就拿这个例子来说,我们分别传入了一个会导致异常的索引还有一个不会导致异常的索引,运行结果如下:
从这里我们可以看到不过是否有异常finally后的语句块都会被执行到,但是我们也发现了一个细节就是在finally语句块之后的语句也执行了。那么既然都执行,这两个语句又有什么区别呢?
区别就是,之要try了,肯定会执行到finally这个语句块,但是finally语句块之后的语句不一定执行得到,比如,我们把代码修改一下:
1 class DemoE3 2 { 3 4 int [] arr = {2,3,4,5}; 5 int index = 0; 6 7 DemoE3(int index) 8 { 9 10 this.index = index; 11 12 } 13 14 void method() 15 { 16 17 try 18 { 19 20 System.out.println("The Five element is "+ arr[index]); 21 22 23 }catch(IndexOutOfBoundsException e) 24 { 25 26 System.out.println("The index out of bouns"); 27 return ;//this position add return yuju,and it will exit the function but it still execute finally 28 29 }finally 30 { 31 32 System.out.println("Array operation done"); 33 34 } 35 36 System.out.println("over"); 37 38 } 39 40 } 41 42 class ExceptionDemo3 43 { 44 45 public static void main(String[] args) { 46 47 DemoE3 d1 = new DemoE3(2); 48 d1.method(); 49 DemoE3 d2 = new DemoE3(6); 50 d2.method(); 51 52 } 53 54 }
也就是说就算在finally执行前,在try catch当中有个return语句,那么此时finally后的语句块,仍然会继续执行,但是在finally语句块之后的语句就不一定会执行得到。
finally的作用是什么呢?
比如我们在日常当中处理数据库的时候,在我们打开数据库操作的过程当中,可能会发生异常,此时如果我们未对数据库进行关闭操作的话,那么数据库则会在一定时间内,认为我们没有断开,会分配一些资源给我们,这个就造成了资源的浪费。设计的思想应该是,我们操作数据库的时候,无论发生异常与否,这个时候我们都要在操作完了之后去关闭他,这个时候就用到了finally这个语句。
那么try catch finally 语句块的特点都有哪些呢?
一、比较常用的就是:
1 try 2 { 3 4 5 }catch(异常类类型 变量) 6 { 7 8 9 }finally 10 { 11 12 13 }
第二个就是没有必要的资源释放的时候,可以省略掉finally:
1 try 2 { 3 4 5 }catch(异常类类型 变量) 6 { 7 8 9 }
第三个就是:
当有资源要释放,但异常不准备自己处理时,这个时候在方法上要声明一个异常,然后finally关闭资源,因为在try语句块当中开启的资源,只能在这个try finally关闭。
1 try 2 { 3 4 5 }finally 6 { 7 8 9 }
异常的应用:
在处理异常的时候,要合理的描述问题,比如说比老师上课,然后电脑冒烟了,这个时候毕老师这个时候应该把情况报告给校方,因为电脑冒烟了,毕老师处理不了,但是又是校方来调用比老师来讲课的,这个时候要把异常反馈给调用者,至于调用者如何处理,这个时候我们是不用去关注的,因为不是本身自己的功能。
异常需要注意的地方:
1、子类在覆盖父类的方法时,如果父类的方法抛出了异常,那么子类的方法也只能抛出父类的异常,或者父类异常的子类。
2、如果父类抛出异常,子类只能抛出父类异常的子集。
简单来说就是:如果父类抛出异常,子类只能抛出父类的异常,或者父类异常的子类,或者父类异常的子集。
注意:如果在子类覆盖父类的方法时,如果父类没有抛出异常,那么子类方法绝对不能抛出异常,否则编译报错,这个时候,只能够去try。这个就跟多态有关系了.....