异常的处理方法
一、Java的异常处理机制:
在 Java的异常处理机制为:抛出异常,捕捉异常。
- 抛出异常:方法中出现异常时,方法会创建对应的异常对象并交付运行时系统,这个异常对象中包含了异常类型和各种异常出现时的异常信息。运行时系统则主要负责寻找处置异常的代码并执行。
- 捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适 的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适 的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。
一个方法所能捕捉的异常,一定是Java代码在某处所抛出的异常。简单地说,异常总是先被抛出,后被捕捉的。
Java规定,对于可查异常必须捕捉、或者声明抛出。允许忽略不可查的RuntimeException和Error。
以上内容引用自: 异常处理的机制。
二、 try - catch - finally :
利用 try-catch-finally 可以捕获及处理异常,其语法格式如下:
try{
    //尝试运行的代码
}catch(异常类型 | 异常的变量名){
    //异常处理代码
}finally{
    //必定会执行的代码- try{}语句块:- try{}内是要尝试运行的代码,是受异常监控的区域,发生异常会抛出相应的异常对象。
- catch(异常类型 | 异常的变量名){}语句块:- 当try{}中发生异常,就要到catch中找对应的异常类,并执行相应的执行代码。如果catch(){}中没找到,异常会从try语句块中抛出,让外层处理。
- catch(){}语句块是带参数的,就是可捕获的异常类型,如- catch(Exception e)。
- catch语句可以有多个,但catch 的范围只能从低到高(子类到父类),只要出现父类,下面的catch语句就不能再出现其子类,如出现 - Exception后就不能出现- Exception的子类:- //编译通过,后面的catch类型不能比上一个catch类型低 try { System.out.println(a/b); } catch (ArithmeticException e) { System.out.println("被除数不能为0"); } catch (NullPointerException e) { System.out.println("NullPointerException"); } catch (Exception e){ System.out.println("Exception"); } catch (Error e){ System.out.println("Error"); } catch (Throwable t){ System.out.println("Throwable"); } finally { System.out.println("最后处理"); } //编译不通过,报错 ArithmeticException 是 Exception 子类 try { System.out.println(a/b); } catch (Exception e) { System.out.println("Exception"); } catch (ArithmeticException e){ System.out.println("ArithmeticException"); } finally { System.out.println("最后处理"); }- 当catch 命中相应的异常类型,就会执行相应的异常处理代码,并跳过后面的catch语句,直接走finally语句。 
 
- 当
- 只要有 - finally{}语句块,只要程序不被强行终止,里面的代码就一定会被执行。即便出现 break, return等流程控制语句也一样要执行- finally语句。- ```java package com.zctou.exception; public class Demo01 { public static void main(String[] args) { int a = 1; int b = 0; try { System.out.println(a/b); } catch (ArithmeticException e) { System.out.println("被除数不能为0"); } finally { System.out.println("最后处理"); } } } //输出: 被除数不能为0 最后处理- finally 不管前面的异常怎么样都会执行,多用于处理善后的事宜,如关闭数据库,关闭文件读取IO流等。 
- 有try就必须至少要有一个catch()或finally语句块。
三、异常抛出 throw 和 throws
抛出异常:异常把异常对象通过向调用层抛出,一层层向上抛直至传递给java虚拟机处理,称为抛出异常。
抛出异常有两种情况:一种是在方法体中主动抛出,另一种则是在方法声明时抛出异常。主动抛出异常,在方法里用关键字throw,在方法声明中用关键字throws。
- 方法体中抛出异常,关键字 - throw,格式如下:- throw new 异常对象- 示例: - package com.zctou.exception; public class Demo02 { public static void main(String[] args) { new Demo02().devided(1,0); } //定义除法,如果被除数为0, 主动抛 ArithmeticException 出异常 public void devided(int a, int b) { if(b==0) { throw new ArithmeticException(); // 文体中主动抛出一个对象 } System.out.println(a/b); } } //输出: Exception in thread "main" java.lang.ArithmeticException at com.zctou.exception.Demo02.devided(Demo02.java:11) at com.zctou.exception.Demo02.main(Demo02.java:6)
- 在方法声明中抛出异常,关键字 - throws,格式如下:- throws 异常类型- 示例: - package com.zctou.exception; public class Demo03 { public static void main(String[] args) { try { new Demo03().devided(1,0); } catch (ArithmeticException e) { System.out.println("外层处理异常"); e.printStackTrace(); } } //假设这个方法内处理不了或者不想处理异常,方法声明中用`throws`抛出异常 public void devided(int a, int b) throws ArithmeticException{ System.out.println(a/b); } } //输出: 外层处理异常 程序不会停止 java.lang.ArithmeticException: / by zero at com.zctou.exception.Demo03.devided(Demo03.java:17) at com.zctou.exception.Demo03.main(Demo03.java:7)
- 不受检异常(RuntimeException):在方法内主动抛出,函数上不用重复声明抛出。
- 若在方法声明中主动抛出异常,调用方法时,不用try-catch-finally处理。
小结:
- throws用于对方法进行声明,如果不声明throws,那么一般的Exception都要在这个方法中处理掉,否则编译发生错误。
- 如果方法声明了throws,可以交给上一级方法处理,但有些Exception可以不用catch捕获,编译也会通过。
 再从头|再回首
再从头|再回首