定义:Java异常是Java提供的一种识别及响应错误的一致性机制。
作用:Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。在有效使用异常的情况下,异常能清晰的回答what, where, why这3个问题:异常类型回答了“什么”被抛出,异常堆栈跟踪回答了“在哪“抛出,异常信息回答了“为什么“会抛出。
java.lang.Throwable |– Error错误:JVM内部的严重问题。无法恢复。程序人员不用处理。 |–Exception异常:普通的问题。通过合理的处理,程序还可以回到正常执行流程。要求编程人员要进行处理。 |–RuntimeException:也叫非受检异常(unchecked exception).这类异常是编程人员的逻辑问题。应该承担责任。Java编译器不进行强制要求处理。 也就是说,这类异常再程序中,可以进行处理,也可以不处理。 |–非RuntimeException:也叫受检异常(checked exception).这类异常是由一些外部的偶然因素所引起的。Java编译器强制要求处理。也就是说,程序必须进行对这类异常进行处理。 复制代码
Java异常机制用到的几个关键字: try、catch、finally、throw、throws。
try-- 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
catch-- 用于捕获异常。catch用来捕获try语句块中发生的异常。
finally-- finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
throw-- 用于抛出异常。
throws-- 用在方法签名中,用于声明该方法可能抛出的异常。
1、显示用try/catch进行处理
try{ //可能会出现异常的代码段; }catch(异常类型1 变量名){ //处理制定类型的异常 //对该类型异常的处理代码段; }catch(异常类型2 变量名){ }finally{ //无论是否发生异常都要执行的代码段; //经常用来清理资源 } 复制代码
2、向上声明:用throws关键字,向外声明本方法可能会抛出的异常列表。
...方法名(参数列表) throws 异常类型1,异常类型2 复制代码
3、手动抛出一个异常:当程序逻辑不符合期望时,要中止后面代码的执行时。在方法的代码段中,可以使用throw关键字手动抛出一个异常。 **注意:**如果手动抛出的是受检异常,那么本方法必须进行处理(应该采用向上声明这个异常);如果手动抛出的是非受检异常,那么可以进行处理,也可以不处理。
基类为***Throwable***,Error和Exception继承Throwable,RuntimeException和IOException、SQLException等继承Exception。
Error 和 RuntimeException 及其子类成为 未检查异常
(unchecked),其它异常成为已 检查异常
(checked)。
检查异常:编译器要求必须处置的异常。
处理方式: 1、通过throws exception继续抛出,消极的方法,一直可以抛到java虚拟机来处理。 2、用try...catch捕获。 注意:检查异常必须处理,捕获或者抛出。
非检查异常:编译器不要求强制处置的异常。这类异常常常只能在运行时才能检查出来,比如空指针,堆溢出等。
处理方式: 1、捕获 2、继续抛出 3、不处理
运行时异常: RuntimeException 类及其子类,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是非检查异常,程序中可以选择捕获处理,也可以不处理。一般由程序逻辑错误引起。
处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,如果有异常产生,则异常将由JVM进行处理,编译也会通过。
对于RuntimeException的子类最好也使用异常处理机制。虽然RuntimeException的异常可以不使用try...catch进行处理,但是如果一旦发生异常,则肯定会导致程序中断执行,所以,为了保证程序再出错后依然可以执行,在开发代码时最好使用try...catch的异常处理机制进行处理。
非运行时异常:非 RuntimeException 类及其子类,如IOException、SQLException等以及用户自定义的Exception异常等,从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。
RuntimeException:运行时异常,在项目运行之后出错则直接中止运行,异常由JVM虚拟机处理。
Exception,:非运行时异常,在项目运行之前必须处理掉。一般由程序员try catch 掉。
自定义异常类需要继承Exception或RunExcption。
注意:覆盖父类某方法的子类方法不能抛出比父类方法更多的异常,所以,有时设计父类的方法时会声明抛出异常,但实际的实现方法的代码却并不抛出异常,这样做的目的就是为了方便子类方法覆盖父类方法时可以抛出异常。
RuntimeException是开发中最容易遇到的,下面列举一下常见的RuntimeException:
1、 NullPointerException :空指针异常;
2、 NumberFormatException :继承IllegalArgumentException,字符串转换为数字时出现。比如int i= Integer.parseInt("ab3");
3、 ArrayIndexOutOfBoundsException :数组越界。比如 int[] a=new int[3]; int b=a[3];
4、 StringIndexOutOfBoundsException :字符串越界。比如 String s="hello"; char c=s.chatAt(6);
5、 ClassCastException :类型转换错误。比如 Object obj=new Object(); String s=(String)obj;
6、 ArithmeticException :算术错误,典型的就是0作为除数的时候。
7、 IllegalArgumentException :非法参数,在把字符串转换成数字的时候经常出现的一个异常,我们可以在自己的程序中好好利用这个异常。