一基础知识
异常是用来描述代码中发生的异常情况的对象当出现引起异常的情况时, 就会抛出异常对象方法可以选择自己处理异常或继续抛出异常异常可以由 Java 运行时系统生成, 也可以手动生成由 Java 抛出的异常与违反语言规则或执行环境约束的基础性错误有关, 手动生成的异常通常用于向方法的调用者报告某些错误条件
二异常类型
所有的异常类型都是 Throwable 的子类 Throwable 位于异常类层次的顶部, 紧随的两个分支是 Exception 和 ErrorException 可用于捕获, 也可用于自定义异常 Error 则定义了在常规环境下不能由程序捕获的异常, 通常是为了响应灾难性失败
三捕获异常
- class Solution {
- public static void main(String[] args) {
- String s = "ABC";
- try {
- int a = Integer.parseInt(s);
- System.out.println(a);
- } catch(NumberFormatException exc) {
- System.out.println("Unknown integer format");
- }
- }
- }
异常被抛出后, 程序控制就会立刻从 try 转移到 catch 中去异常位置之后的语句不会执行
- import java.util.Scanner;
- class Solution {
- public static void main(String[] args) {
- Scanner in =new Scanner(System. in );
- String s = in.nextLine();
- String t = in.nextLine();
- try {
- int a = Integer.parseInt(s);
- int b = Integer.parseInt(t);
- System.out.println(a / b);
- } catch(ArithmeticException exc) {
- System.out.println("Divisor cannot be 0");
- } catch(NumberFormatException exc) {
- System.out.println("Unknown integer format");
- }
- }
- }
单块代码可能会出现多种异常情况, 可通过指定多条 catch 语句来捕获所有可能出现的异常当异常抛出时, 会按顺序检查每条 catch 语句, 直到遇到可以匹配的 catch 语句, 之后会忽略剩余的 catch 语句若异常无法遇到匹配的 catch 语句, 将会无法被捕获, 程序会因异常而中断
当使用多条 catch 语句时, 子类异常捕获必须位于所有超类之前若超类异常捕获位于子类之前, 那么子类异常将永远无法被捕获
四内置异常
在 Java 内置的异常类中, 最常用的是 RuntimeException 的子类
所有方法不需要指明会抛出这些异常, 称为未经检查的异常
四自定义异常
Exception 类没有定义任何方法, 但继承了 Throwable 提供的方法
可通过继承 Exception 来实现自定义异常, 可通过重写 toString 方法来修改异常描述
- import java.util.Scanner;
- class MyException extends Exception {
- MyException(String msg) {
- super(msg);
- }
- @Override
- public String toString() {
- return "MyException:" + super.getMessage();
- }
- }
- class Solution {
- static int divide(int a, int b) throws MyException {
- if (b == 0)
- throw new MyException("Divisor cannot be 0");
- return a / b;
- }
- public static void main(String[] args) {
- Scanner in = new Scanner(System.in);
- int a = in.nextInt();
- int b = in.nextInt();
- try {
- int res = divide(a, b);
- System.out.println(res);
- } catch (MyException exc) {
- System.out.println(exc);
- }
- }
- }
五链式异常
通过链式异常, 可以为异常关联另一个异常第二个异常是引发第一个异常的原因, 称为引发异常或背后异常可通过 getCause 方法获取当前异常的背后异常, 通过 initCause 或构造函数关联背后异常, 并且背后异常只能设置一次
- class Solution {
- static void throwerA() {
- IndexOutOfBoundsException exc = new IndexOutOfBoundsException("Index out of bounds");
- exc.initCause(new NullPointerException());
- throw exc;
- }
- static void throwerB() throws Exception {
- throw new Exception("Null pointer cause exception", new NullPointerException());
- }
- public static void main(String[] args) {
- try {
- throwerA();
- } catch(IndexOutOfBoundsException exc) {
- System.out.println(exc.toString());
- System.out.println(exc.getCause().toString());
- }
- try {
- throwerB();
- } catch(Exception exc) {
- System.out.println(exc.toString());
- System.out.println(exc.getCause().toString());
- }
- }
- }
六多重捕获
可通过单独的 catch 语句捕获多个异常
- import java.util.Scanner;
- class Solution {
- public static void main(String[] args) {
- Scanner in = new Scanner(System.in);
- int a = in.nextInt();
- int b = in.nextInt();
- int[] nums = {1, 2, 3};
- try {
- int res = a / b;
- nums[a] = res;
- } catch (ArithmeticException | ArrayIndexOutOfBoundsException exc) {
- System.out.println(exc.toString());
- }
- }
- }
来源: http://www.bubuko.com/infodetail-2497059.html