java中的异常处理是通过五个关键字:try , catch , finally , throw 和 throws。
try-catch块
示例
import java.util.Scanner; public class MyMainTry { public static void main(String[] args) { Scanner input=new Scanner(System.in); try { System.out.print("被除整数"); int a=input.nextInt(); System.out.print("整数"); int b=input.nextInt(); }catch(Exception ex) { System.err.println("除数不能为零"); }
try-catch块的执行流程比较简单,首先执行的是try语句块中的语句,
1.如果try块中的语句正常执行没有发生异常,那么catch中的所有语句都将会被忽略。
2.如果try语句在执行的过程中出现了异常,那么会和catch声明的异常相匹配,那么try块下面其余的语句将被忽略。
3.如果try语句块在执行过程中遇到异常,而抛出的异常在catch中没有声明,那么程序直接被退出。
调用异常对象的方法输出异常信息
void printStackTrace();:输出异常的堆栈信息
String getMessage();:返回异常信息描述字符串
--常见的异常类型
异常层次结构的根系:Execption
算术异常类:ArithmeticExecption
空指针异常类:NullPointerException
类型强制转换异常:ClassCastException
数组负下标异常:NegativeArrayException
数组下标越界异常:ArrayIndexOutOfBoundsException
字符串转换为数字异常:NumberFormatException
操作数据库异常:SQLException
--try-catch-finally块
示例
public class MyMainTry { public static void main(String[] args) { Scanner input=new Scanner(System.in); try { System.out.print("被除整数"); int a=input.nextInt(); System.out.print("整数"); int b=input.nextInt(); int c=a/b; System.out.println(c); }catch(Exception ex) { ex.printStackTrace(); }finally { System.out.println("退出系统"); } } }
以上可以看出finally 关键字是无论是否发生异常finally 中的语句都执行的,那么finally 有没有不被执行的唯一条件呢?
答案是有的:在异常处理的代码块中执行 System.exit(1);异常退出java虚拟机程序,System.exit(0);:正常退出
示例
public static void main(String[] args) { Scanner input=new Scanner(System.in); try { System.out.print("被除整数"); int a=input.nextInt(); System.out.print("整数"); int b=input.nextInt(); int c=a/b; System.out.println(c); }catch(Exception ex) { System.err.println("出现错误"); System.exit(1); //异常退出 }finally { System.out.println("chengxujieshu"); } }
--多重catch块
示例
try { int num=5/0; }catch(NullPointerException ex) { System.err.println("出现错误"+ex.getMessage()); ex.printStackTrace(); }catch(ArithmeticException ex) { System.err.println("出现错误"+ex.getMessage()); ex.printStackTrace(); }catch(Exception ex) { System.err.println("出现错误"+ex.getMessage()); ex.printStackTrace(); } }
多重catch块只匹配相应的异常一次,但排序顺序必须是子类到父类,然后继续执行下面的语句。
声明异常--throws
public class ExceptionTest { //声明:对异常不处理,收到异常我也向外抛 public static void main(String[] args) throws Exception{ DivDemo dd =new DivDemo(); int resultD = dd.div(10, 0); System.out.println("resultD' value is :"+resultD); System.out.println("over!"); } } class DivDemo{ //在功能上通过throws的关键字-- //--声明:调用该方法有可能会出现问题,可能向外抛异常 public int div(int a,int b) throws Exception { return a/b; } }
调用别人的程序方法,而别人的方法上声明了可能有异常
抛出异常--throw
throw
–关键字throw用于显式抛出异常。
–抛出异常后处理:
.使用try-catch捕获异常。
.使用throws声明异常。
–语法
.throw new 异常类构造方法
.例如: throw new Exception();
示例
public class ThrowTest { public static void main(String[] args) { try { // 调用声明抛出Checked异常的方法,要么显式捕获该异常 // 要么在main方法中再次声明抛出 throwChecked(-3); } catch (Exception e) { System.out.println(e.getMessage()); } // 调用声明抛出Runtime异常的方法既可以显式捕获该异常, // 也可不理会该异常 throwRuntime(3); } public static void throwChecked(int a)throws Exception { if (a > 0) { // 自行抛出Exception异常 // 该代码必须处于try块里,或处于带throws声明的方法中 throw new Exception("a的值大于0,不符合要求"); } } public static void throwRuntime(int a) { if (a > 0) { // 自行抛出RuntimeException异常,既可以显式捕获该异常 // 也可完全不理会该异常,把该异常交给该方法调用者处理 throw new RuntimeException("a的值大于0,不符合要求"); } } }
异常的类型
- Error是无法处理的异常,比如OutOfMemoryError,一般发生这种异常,JVM会选择终止程序。因此我们编写程序时不需要关心这类异常。
-
Exception,也就是我们经常见到的一些异常情况,这些异常是我们可以处理的异常,是所有异常类的父类。
-
unchecked exception(非受查异常),包括Error和RuntimeException,比如常见的NullPointerException、IndexOutOfBoundsException。对于RuntimeException,java编译器不要求必须进行异常捕获处理或者抛出声明,由程序员自行决定。
-
checked exception(受查异常),也称非运行时异常(运行时异常以外的异常就是非运行时异常),由代码能力之外的因素导致的运行时错误。java编译器强制程序员必须进行捕获处理,比如常见的有IOExeption和SQLException。如果不进行捕获或者抛出声明处理,编译都不会通过。
-
典型的RuntimeException包括NullPointerException、IndexOutOfBoundsException、IllegalArgumentException等。
- 典型的非RuntimeException包括IOException、SQLException等。
- Throwable:所有异常类型都是Throwable类的子类,它派生了两个子类,Error和Exception。