处理异常

异常处理

1.异常

什么是异常?异常是在程序中导致程序中断运行的一种指令流。

示例:

public class Demo {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个数字:");
        /*InputMismatchException:由 Scanner抛出,表示检索到的令牌与预期类型的模式不匹配,或者令牌超出预期类型的范围。*/
        int x = input.nextInt();// 输入a 会发生异常:InputMismatchException,程序会停止,不会执行Line 6
        System.out.println("请再输入一个数字:");
        /*ArithmeticException:发生异常算术条件时抛出。 例如,整数“除以零”会抛出此类的实例。 ArithmeticException对象可以由虚拟机构建,就像suppression were disabled and/or the stack trace was not writable一样 。*/
        int y = input.nextInt();// 输入0 12行会报错:ArithmeticException,计算异常
        System.out.println(x/y);// y=0导致此时x/y会实例一个对象(相应的异常对象),如果没有代码处理,就会返回main方法,而捕获异常就是拦截异常不让他返回main方法
    }
}

运行结果:

image-20211203135241167

异常体系:

Object类:

  • Throwable类:
    1. Error类:不能操作处理的
    2. Exception类:可以操作处理的
      1. 非受检异常:RuntimeException,又叫运行时异常image-20211202163536624
      2. 受检异常:非RuntimeException,又叫非运行时异常

Day29.异常处理_异常体系

2.处理异常

对异常进行处理。格式如下:

try {
    // 有可能发生异常的代码块
} catch (异常类型1 对象名1) {
    // 异常处理操作
} catch (异常类型2 对象名2) {
    // 异常处理操作
} ...
finally {
    // 异常统一出口
}

2.1 try+catch处理异常流程

  1. 一旦产生异常,则系统会自动产生一个异常类的实例化对象。
  2. 那么,此时如果异常发生在try语句,则会自动找到匹配的catch语句执行,如果没有在try语句中,则会将异常抛出给调用方法的方法里。
  3. 所有的catch根据方法的参数来匹配异常类的实例化对象,如果匹配成功,则表示由此catch进行处理。

示例:

package com.kaikeba.demo;

import java.util.InputMismatchException;
import java.util.Scanner;
/**
 * 功能描述
 * @author Mengxiangkuan
 * @date 2021/12/3
 */
public class Demo2 {
    public static void main(String[] args) {
        input();
        System.out.println("执行结束!");
    }
    /**
     * 输入数字计算结果
     * @author Mengxiangkuan
     * @date 2021/12/3
     */
    public static void input() {
        try {
            Scanner input = new Scanner(System.in);
            System.out.println("请输入数字:");
            int num1 = input.nextInt();
            System.out.println("请输入数字");
            int num2 = input.nextInt();
            int num3 = num1/num2;
            System.out.println("计算结果是:" + num3);
        }catch (InputMismatchException e) {// 输入格式异常 如果输入的不是要求的格式会报错
            System.out.println("请输入数字!");
            input();
        }catch (ArithmeticException e) {// 算数异常 除数为0
            System.out.println("除数不能为0");
            input();
        }
    }
}

运行结果:

image-20211203141123281

2.2 处理多异常格式

  1. 格式一:

    try {
                Scanner input = new Scanner(System.in);
                System.out.println("请输入数字:");
                int num1 = input.nextInt();
                System.out.println("请输入数字");
                int num2 = input.nextInt();
                int num3 = num1/num2;
                System.out.println("计算结果是:" + num3);
            }catch (InputMismatchException e) {// 输入格式异常 如果输入的不是要求的格式会报错
                System.out.println("请输入数字!");
                input();
            }catch (ArithmeticException e) {// 算数异常 除数为0
                System.out.println("除数不能为0");
                input();
            }
    
  2. 格式二:很少用,仅作了解

    try {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入数字:");
        int num1 = input.nextInt();
        System.out.println("请输入数字:");
        int num2 = input.nextInt();
        int num3 = num1/num2;
        System.out.println("计算结果是:" + num3);
    }catch (InputMismatchException|ArithmeticException e) {// 如果try块产生这两种异常就执行这个代码块
        System.out.println("输入有误!");
    }
    
  3. 格式三:常用

    try {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入数字:");
        int num1 = input.nextInt();
        System.out.println("请输入数字:");
        int num2 = input.nextInt();
        int num3 = num1/num2;
        System.out.println("计算结果是:" + num3);
    }catch (RuntimeException e) {// 如果try块产生这任何异常就执行这个代码块  扩大异常形态范围
        System.out.println("输入有误!");
    }
    

2.3 finally关键字

必然执行的异常统一处理出口。无论是否发生异常,finally必然执行。

面试题:finally在何种情况下不被执行?

答案:在finally执行之前程序被关闭了finally不会执行,比如:停电,电脑关机了,或者在执行finally之前代码退出。

示例:

public static void input() {
        try {
            int length = 10;
            for(int i = 0;i < length;i++) {
                System.out.print(i + "\t");
            }
            return;// 强制结束方法
        }catch (Exception e) {
        }finally {
            System.out.println("我是小学生。");// finally也是会执行
        }
    }

运行结果:image-20211204000818300

/**
 * @author 孟祥宽
 * @ClassName Demo6
 * @description finally不执行的情况
 * @date 2021/12/4 0:15
 */
public class Demo6 {
    public static void main(String[] args) {
        // 出现了异常! 没有执行finally
        input();
    }
    public static void input() {
        try {
            int a = 10;
            int b = 0;
            // 计算异常
            System.out.println(a/b);
        }catch (Exception e) {
            System.out.println("出现了异常!");
            // 退出jvm  0:正常退出  其他:非正常退出
            System.exit(0);
        }finally {
            System.out.println("这里执行了吗?");
        }
    }
}

运行结果:

image-20211204001943916

引用类型和基本数据类型在执行finally代码的区别:

示例:

/**
 * @author 孟祥宽
 * @ClassName Demo5
 * @description finally处理异常测试
 * @date 2021/12/3 23:56
 */
public class Demo5 {
    public static void main(String[] args) {
        Person person = input();
        // 输出 默认
        System.out.println(person.getName());
        int sum = sum();
        // 输出 1 并未输出finally里的值
        System.out.println(sum);
    }
    /**
     * 引用数据类型
     * @author Mengxiangkuan
     * @date 2021/12/4
     * @return com.kaikeba.demo.Person
     */
    public static Person input() {
        Person person = new Person();
        try {
            person.setName("孟祥宽");
        }catch (Exception ignored) {
        }finally {
            person.setName("默认");
        }
        return person;
    }
    /**
     * 基本数据类型
     * @author Mengxiangkuan
     * @date 2021/12/4
     * @return int
     */
    public static int sum() {
        int index = 1;
        try {
            // 返回的index是 1 这个index是新备份的index
            return index;
        }catch (Exception ignored) {
        }finally {
            index = 5;
        }
        return index;
    }
}

2.4 throws关键字

throws此关键字主要在方法上声明,表示方法中不处理异常,而是交给调用处处理

格式:

返回值 方法名称() throws Exception {}

示例:

/**
 * @author 孟祥宽
 * @ClassName Demo7
 * @description throws关键字
 * @date 2021/12/4 0:32
 */
public class Demo7 {
    public static void main(String[] args) {
        sum("a","2");
    }
    /**
     * throws抛出异常
     *
     * 异常是否跑出去? 如果是因为传参导致异常,应该将异常通过throws抛出去
     *
     * @author Mengxiangkuan
     * @date 2021/12/4
     * @param a 字符串1
     * @param b 字符串2
     * @throws NumberFormatException 传入的参数不对
     */
    public static void sum(String a, String b) throws NumberFormatException{
        int sum = Integer.parseInt(a) + Integer.parseInt(b);
        System.out.println(sum);
    }
}

2.5 throw关键字

表示在程序中人为的抛出一个异常。

示例:


/**
 * @author 孟祥宽
 * @ClassName Student
 * @description throw关键字
 * @date 2021/12/4 0:50
 */
public class Student {
    private String name;
    private int age;
    public final static int AGE_MAX = 180;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age > AGE_MAX || age < 0) {
            RuntimeException e = new RuntimeException(age + "不合理,要求小于" + AGE_MAX + ",大于0");
            throw e;
        }
        this.age = age;
    }
    

/**
 * @author 孟祥宽
 * @ClassName StudentTest
 * @description Student的测试类
 * @date 2021/12/4 0:52
 */
public class StudentTest {
    public static void main(String[] args) {
        Student student = new Student();
        student.setAge(-1);
    }
}

运行结果:

image-20211204005417894

posted @ 2021-12-04 16:11  雨溟  阅读(65)  评论(0)    收藏  举报