Java笔记:异常处理

Posted arseneyao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java笔记:异常处理相关的知识,希望对你有一定的参考价值。

一、基础知识

异常是用来描述代码中发生的异常情况的对象。当出现引起异常的情况时,就会抛出异常对象。方法可以选择自己处理异常或继续抛出异常。异常可以由Java运行时系统生成,也可以手动生成。由Java抛出的异常与违反语言规则或执行环境约束的基础性错误有关,手动生成的异常通常用于向方法的调用者报告某些错误条件。

 

二、异常类型

所有的异常类型都是Throwable的子类。Throwable位于异常类层次的顶部,紧随的两个分支是Exception和Error。Exception可用于捕获,也可用于自定义异常。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());
        }
    }
}

 

以上是关于Java笔记:异常处理的主要内容,如果未能解决你的问题,请参考以下文章

Java异常处理机制

Java笔记:异常处理

java 反射代码片段

java中的try-catch-finnal异常处理(学习笔记)

Java基础学习笔记十八 异常处理

Java笔记八,深度解析Java线程池的异常处理机制