1、异常和错误
在Java程序的运行过程中,如果发生了意外事件(发生了错误或异常),则该意外会被封装成为一个对象,并把它提交给运行时的系统,寻求相应的代码来处理。意外事件在Java中分为两类,即错误和异常;而把这个意外对象的生成和提交过程,我们称之为抛出。
在Java中:
● 错误 - 不受控的,程序无法处理的
● 异常 - 容易排查的,可以处理的
2、异常的体系结构
Throwable
类是 Java 语言中所有错误或异常的超类。其两个子类:Error(错误)、Exception(异常)。
Error是程序无法处理的,比如OutOfMemoryError、ThreadDeath等,出现如此情况我们往往无能为力,只能交给JVM自行处理,大多数情况下,JVM会选择终止线程(真是简单粗暴...);而Exception就是程序可以处理的异常,也是我们重点要理解的部分。
3、异常的处理
3.1try catch
1 public static void main(String[] args) { 2 Date date = null; 3 int[] arr = new int[] { 0, 1, 2 }; 4 try { 5 int i = arr[5]; 6 System.out.println(i); 7 long time = date.getTime(); 8 System.out.println(time); 9 } catch (NullPointerException e) { 10 System.out.println("空指针异常发生了,好像我应该做些什么"); 11 } catch (IndexOutOfBoundsException e) { 12 System.out.println("数组越界了"); 13 } catch (Exception e) { 14 System.out.println("发生了异常"); 15 } 16 }
这个例子最后只会输出 "数组越界了",因为异常只被捕捉一次,且后面的代码不再执行。即使下面出现其他异常,也不会执行。
1 public static void main(String[] args) { 2 Date date = null; 3 int[] arr = new int[]{0, 1, 2}; 4 try { 5 int i = arr[5]; 6 System.out.println(i); 7 long time = date.getTime(); 8 System.out.println(time); 9 } catch (Exception e) { //错误的写法,异常捕获的顺序只能从子类到父类 10 System.out.println("发生了异常"); 11 } catch (NullPointerException e) { 12 System.out.println("空指针异常发生了,好像我应该做些什么"); 13 } catch (IndexOutOfBoundsException e) { 14 System.out.println("数组越界了"); 15 } 16 }
注意catch异常的顺序,如上例中的写法是无法通过编译的,因为Exception是所有异常的父类,而catch块必须按照从子类到父类的顺序进行编写。
3.3finally
在异常处理中,还有一个语句块叫 finally,可以不写,一旦写上,那么有且只能有一个finally语句块,该部分的代码内容总是会执行的。一般是跟在最后的catch块之后。
需要注意的是,finally是可选的,即可以只有try和catch,同时要知道的是:
● 可以只有try和finally
● 可以只有try和catch
● 不能只有try
3.4异常处理中的return
在Java语言的异常处理中,finally块的作用就是为了保证无论出现什么情况,finally块里的代码一定会执行。而return意味着结束了对当前函数的调用并跳出这个函数体,那么如果try块中或者catch块中出现了return,finally又如何是好?
下面的函数最终会返回多少?
1 public static int func (){ 2 try{ 3 return 1; 4 }catch (Exception e){ 5 return 2; 6 }finally{ 7 return 3; 8 } 9 } 10 }
只需要记住,无论如何finally语句都要执行(除非调用了System.exit()方法)。同时,如果:
● finally中没有return,那么不会影响try或catch中return的结果,但是finally还是会执行的
● finally中有return语句,那么会覆盖掉try或catch中的return的结果,再进行返回