异常

异常是指程序运行时发生的不正常现象,异常不是错误。错误会提前结束程序,实行到有异常的地方程序就终止了。


先定义一个方法,计算两个数的商

public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        System.out.println("请输入被除数:");
        int a=input.nextInt();
        System.out.println("请输入除数:");
        int b=input.nextInt();
        System.out.println("商为:"+(a/b));
        System.out.println("程序结束!");
}

在运行方法时,若输入的除数为0,会导致结果无意义和逻辑上的矛盾,这时就会报出异常

ArithmeticException     也就是算数错误异常


接下来,就来处理异常

(1)用try-catch块自己处理异常

把可能出现异常的程序段放在try{}块中,出现异常后,会被catch{}块捕获,并做出处理

依然是刚刚的两数相除的方法

public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        try {
            System.out.println("请输入被除数:");
            int a=input.nextInt();
            System.out.println("请输入除数:");
            int b=input.nextInt();
            System.out.println("商为:"+(a/b));
        } catch (ArithmeticException arithmeticException) {
            System.out.println("除数不能为0");
        }
        System.out.println("程序结束!");
    }

处理异常后,这时输出除数时再输出0,就会自动处理异常,判断异常为ArithmeticException,根据此异常针对处理,处理后输出“除数不能为0”,然后结束程序,保证了整个程序不会中断,而是完整的走完了整个进程。


当然,要是异常有多个,不止一个算数异常怎么办?在try-catch中,catch块是可以有多个的,一个catch块对应一个异常,已久以两数相除的方法为例

public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        try {
            System.out.println("请输入被除数:");
            int a=input.nextInt();
            System.out.println("请输入除数:");
            int b=input.nextInt();
            System.out.println("商为:"+(a/b));
        } catch (InputMismatchException inputMismatchException) {
            System.out.println("输入的值类型不匹配");
        } catch (ArithmeticException arithmeticException){
            System.out.println("除数不能为0");
        } catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("程序结束!");
    }

因为输入时,规范了输入的数据类型只能是整型Int,如果输入了非整型的数据,就会报出InputMismatchException      也就是欲得到数据类型与实际输入类型不匹配异常

如输入3.2小数,abc字符等情况,于是就出现了多个catch块处理异常的情形,既可处理算数异常,又可处理数据不匹配异常。当然也可写作

Exception  表示所有的异常

只需在catch块中放Exception那么这个catch块就可处理所有异常类型,无论什么异常都会执行Exception这个catch块,因为Exception是异常层次的根类。

但在写catch块是要注意,*******子异常在前,父异常在后******


(2)用throwthrows抛出异常

throw用来抛出异常,throws用来声明异常,把throw抛出的异常给调用者,由调用者来处理。
注:谁调用,那么异常就抛给谁,由调用者来处理异常,同理,调用者也可以再往外抛出。但最终一定要对异常进行处理。
所以在程序开发中,尽量少抛出异常,多用try-catch块自己处理

案例:

谁调用cal()方法,异常就抛给谁,由调用cal()方法的调用者处理异常

public static void cal() throws InputMismatchException,ArithmeticException {
        Scanner input=new Scanner(System.in);
        int a,b;
        System.out.println("请输入被除数");
        if (input.hasNextInt()) {//判断扫描仪输入的值是否为数字
            a=input.nextInt();
        }else{
            System.out.println("请输入数字");
            //抛出输入类型不匹配异常
            throw new InputMismatchException();
        }

        System.out.println("请输入除数");
        if(input.hasNextInt()){
            b=input.nextInt();
            if(b==0){
                System.out.println("除数不能为0");
                //抛出算数异常
                throw new ArithmeticException();
            }
        }else{
            System.out.println("请输入数字");
            throw new InputMismatchException();
        }

        System.out.println("商为:"+(a/b));
        System.out.println("程序结束");
    }

    public static void main(String[] args) {
        cal();
    }

finally-return-exit关键字的作用

(1)finally用在try-catch块后,表示最终的,无论如何都会执行的块。

public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        try {
            System.out.println("请输入被除数:");
            int a=input.nextInt();
            System.out.println("请输入除数:");
            int b=input.nextInt();
            System.out.println("商为:"+(a/b));
        } catch (ArithmeticException arithmeticException) {
            System.out.println("除数不能为0");
        }finally{
            System.out.println("程序结束!");
        }
    }

可以吧输出语句放在finally块中

(2)return用在方法中,表示结束方法并返回结果,但是return和finally都存在时,即使有return,finally块也会执行。

(3)System.exit()表示结束程序退出,会返回exit()方法中传入的值。如果执行到exit(),那么后面的return和finallly都不会

案例:

public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        try {
            System.out.println("请输入被除数:");
            int a=input.nextInt();
            System.out.println("请输入除数:");
            int b=input.nextInt();
            //exit():会强制结束并退出程序,且返回输入的状态码
            //exit()后的return和finally都不执行
            System.exit(1);
            System.out.println("商为:"+(a/b));
            //只有return没有exit的情况下,程序到此结束,后面的finally会执行
            return;
        } catch (InputMismatchException inputMismatchException) {
            System.out.println("输入的值类型不匹配");
        } catch (ArithmeticException arithmeticException){
            System.out.println("除数不能为0");
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            System.out.println("程序结束!");
        }

综上,3者的优先级为System.exit(0)>finally>return


异常的语法为:

(1)使用try-cate块自己处理异常
try{
    //代码块1,如果出现了问题,会被catch捕获,如果没有出问题,catch块不会执行;
}catch(Exception e){
    //代码块2,出现问题才会生效,如接上的警察;
}finally{
    //代码块3,有没有出问题都会执行的;
}
//代码块4,后续的代码块;

下方整理了几个常见的异常:

    异常名                             说明
Exception                           异常层次结构的根类
ArithmeticException                 算数错误情形,如以零作除数
ArrayIndexOutOfBoundsException      数组下标越界
NullPointerException                尝试访问 null 对象成员
ClassNotFoundException              不能加载所需的类
InputMismatchException              欲得到数据类型与实际输入类型不匹配
IllegalArgumentException            方法接收到非法参数
ClassCastException                  对象强制类型转换出错
NumberFormatException               数字格式转换异常,如把"abc"转换成数字

补充

自定义异常

一个类只要继承类Exception,那么这个类就是自定义异常

public class MyException extends Exception{
    public MyException() {
    }

    public MyException(String message) {
        super(message);
    }

    public MyException(String message, Throwable cause) {
        super(message, cause);
    }

    public MyException(Throwable cause) {
        super(cause);
    }

    public MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

异常的分类

编译时异常:程序写完就报出错误        通常表现为部分语句下方有红色波浪线

运行时异常:程序运行时报出错误        如除数为0时


异常分类结构

                    Object
                      |
                   Throwable
                      |
  Error                                 Exception
    |                                       |
 AWTError                  SQLException          RuntimeException
ThreadDeath             ClassNotFoundException   ArithmeticException
                                                 NullPointerException
                                                 NumberFormatException

(1)Throwable        是类不是接口
(2)Error        是系统的错误,不是程序可以解决的,不需要我们处理

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐