Java入门学习之自定义异常报错

一、为什么要学习自定义异常报错?

在我们平常写代码时都会出现异常报错的情况,我们可以根据报错的信息来解决代码存在的bug。然而,Java无法为全部问题都提供异常类来提醒我们。因此我们在进行项目开发的时候,程序员A在调用程序员B写的代码时出现了bug没有用异常类的形式进行输出或者反馈给程序员A,那么A则不知道调用是否成功。所以我们自己定义异常类来提醒我们调用方法失败,方便调用者知道自己是否调用成功,如果调用不成功也可以知道调用错误的原因。

二、异常的体系是什么?

异常体系如下

java process 获取HWND_java process 获取HWND

其中,错误主要分为两种:
1、Error代表的是系统级别的错误(属于严重错误),这个错误是给sun公司自己使用的,不需要我们理会。
2、Exception才叫异常,它代表的才是我们程序可能出现的问题。所以程序员通常会用Exception和它的“孩子们”来封装程序可能出现的问题。一般它的孩子分为两种,一种是运行时异常RuntimeException。一种时编译时异常,在上面的图中用其它异常来表示了。
一般我们自定义异常类都是第二种。

二、自定义异常的作用

我们可以让上层调用者知道自己调用是否成功,如例2.1所示:
例2.1:

public class RegexTest3 {
    public static void main(String[] args) throws Exception{
        Age(250);
    }
    public static void Age(int age) throws Exception{
        if(age >= 0 && age <= 150){
            System.out.println("年龄符合要求");
        }
        else {
            System.out.println("年龄非法");
        }
    }
}

在上面的代码中,在main中调用了Age()方法,如果年龄超过了规定范围,只能输出一个“年龄非法”,相反,如果我们采用了异常类的形式,如例2.2和2.3所示:
例2.2:

public class RegexTest3 {
    public static void main(String[] args) throws Exception{  //这里的throws Exception 也是把问题抛出给上一次,也就是JVM虚拟机。如果不想再次抛出,则可以利用try-catch来捕获异常,下面将会有例子展示。
        Age(250);
    }
    public static void Age(int age) throws Exception{ //throws Exception 是把问题抛出给上一层
        if(age >= 0 && age <= 150){
            System.out.println("年龄符合要求");
        }
        else {
        	//用一个异常对象来封装这个问题
            throw new AgeError("年龄不符合要求");
        }
    }
}

例2.3:

//经过封装的异常类
public class AgeError extends Exception{
    public AgeError() {
    }

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

如果我们采用上面异常类的形式,那么调用者就能够清楚的知道调用出现了问题,并报错了。下面时报错的相关信息

D:\Software\JDK\bin\java.exe "-javaagent:D:\Software\IntelliJ IDEA 2021.3.3\lib\idea_rt.jar=61437:D:\Software\IntelliJ IDEA 2021.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\JAVA_Project\zhengze\out\production\zhengze Zheng_ze_biao_da.RegexTest3
Exception in thread "main" Zheng_ze_biao_da.AgeError: 年龄不符合要求
	at Zheng_ze_biao_da.RegexTest3.Age(RegexTest3.java:12)
	at Zheng_ze_biao_da.RegexTest3.main(RegexTest3.java:5)

三、异常常见的处理方式

出现异常时,一般开发有两种常见的处理方式,分别如下:
1、捕获异常,记录异常后并响应合适的信息或者内容给用户
例3.1:

import java.util.Scanner;

public class RegexTest3 {
    public static void main(String[] args){
        try {
            Age();
        } catch (Exception e) {
            System.out.println("您当前操作有问题"); //这里就是将异常通过合适的信息展示给用户
            e.printStackTrace(); //会给出详细的报错信息
        }
    }
    public static void Age() throws Exception{
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的年龄:");
        int age = sc.nextInt();
        if(age >= 0 && age <= 150){
            System.out.println("年龄符合要求");
        }
        else {
            throw new AgeError("年龄不符合要求");
        }
    }
}

如果输入的年龄存在问题,那么执行的结果如下:

请输入您的年龄:
1190
您当前操作有问题  //这里就是将出现的问题通过合适的信息或者内容展示给用户,下面就是给出了详细的报错信息,如果把e.printStackTrace();进行注释,则下面的信息将不会出现
Zheng_ze_biao_da.AgeError: 年龄不符合要求
	at Zheng_ze_biao_da.RegexTest3.Age(RegexTest3.java:22)
	at Zheng_ze_biao_da.RegexTest3.main(RegexTest3.java:8)

Process finished with exit code 0

2、捕获异常,并且尝试修复
例3.2:

import java.util.Scanner;

public class RegexTest3 {
    public static void main (String[] args){
        while (true) {
            try {
                System.out.println(Age());
                break;
            } catch (Exception e) {
                System.out.println("您当前操作有问题吗,请您重新输入!!"); //这里就是将异常通过合适的信息展示给用户
            }
        }
    }
    public static double Age() throws Exception {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入您的年龄:");
            int age = sc.nextInt();
            if (age >= 0 && age <= 150) {
                System.out.println("年龄符合要求");
                return age;
            } else {
                System.out.println("您输入的年龄是不符合要求的");
            }
        }
    }
}

上面这段代码将会捕获异常并尝试进行修复,直到异常不存在,执行结果如下所示。

请输入您的年龄:
190
您输入的年龄是不符合要求的
请输入您的年龄:
aedfd
您当前操作有问题吗,请您重新输入!!
请输入您的年龄:
14
年龄符合要求
14.0

Process finished with exit code 0

注意::一般如果A调用B,B调用C,然后C存在异常的话,C可以把异常throws抛给B,然后B再抛给A,最后在A中利用上面两种解决异常的方式去解决问题。