Java异常

异常机制其实是帮助找到程序中出现的问题

  • Error:严重错误Error,无法通过异常处理的错误,好比绝症,只能是事先预防。

  • Exception:异常,异常产生后程序员可以通过代码的方式进行纠正处理,使程序能够继续进行下去。

Java异常处理的五个关键字:try catch finally throw throws

  1. 创建一个异常对象,封装一些提示信息(信息可以自己编写)。

  2. 需要将这个异常对象告知给调用者,通过关键字throw就可以完成。throw抛出一个异常对象

    throw new 异常类名(参数)
    // 给调用者抛出一个空指针异常
    throw new NullPointerException("要访问的arr数组不存在,值为null");
    // 给调用者抛出一个索引越界异常
    throw new IndexOutOfBoundsException("该索引超出了引用的范围");

将问题标识出来,报告给调用者,如果方法内通过throw抛出了一个编译期异常,又没有通过捕获处理(try..catch),那么必须通过throws进行声明,让调用者去处理。

关键字throws运用在方法的声明上,用于表示不处理异常,提醒调用者该方法的调用携带的是有异常信息,谁调用谁处理。

修饰符  返回值类型  方法名(参数列表) throws 异常类名1,异常类名2,....{}
public class DemoThrows {
    public static void main(String[] args) {
        read("C:/a.txt");
    }
    public static void read(String path) throws FileNotFoundException{
        // 校验 如果你传递的路径不是以.txt的结尾的,抛出调用者文件找不到异常
        if (!path.endsWith(".txt")) {
            // 抛出一个文件找不到异常
            throw new FileNotFoundException("文件找不到");
        }
    }
}
捕获异常 try...catch

如果异常出现的话,会立刻终止程序。

  1. 如果使用throws关键字来声明式处理,由该方法的调用者来处理(很危险)

  2. 在方法中使用try...catch的语句块来处理异常

try {
    // 编写的可能会出现的异常代码
    //.....
} catch (异常类型 e) {
    // 处理异常的逻辑代码
    // 记录日志 // 打印异常信息 // 继续往上抛
}

try:该语句块中可能出现异常的代码

catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理。

备注:try和catch都不能单独使用,一般建议连用。

finally:有一些特定的代码无论异常是否发生,都需要执行。当程序发生异常时,会引发程序的跳跃性,导致有一些代码加载不到,而finally语句块就是用来解决这样的问题的,在finally语句块中存放的代码一般都是一定会被执行到的

try {
    // 
} catch (异常类型 e) {
    // ....
}
.....
finally {
    //....
}    

备注:中间的catch语句块可以省略,finally不能单独使用,建议连用。

1. 如果finally语句块中有return语句,永远返回的是finally语句块中的结果值
2. 当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会被执行到,否则finally永远会执行。

自定义异常

什么是自定义异常类?

在开发中根据自己的业务的异常情况来定义的异常类。

例如:我想自定义一个业务逻辑异常类:注册异常 RegisterException。

异常类如何定义?

  1. 自定义一个编译期异常,自定义类继承于java.lang.Exception

  2. 自定义一个运行期异常类,自定义类 继承于java.lang.RuntimeException

自定义异常例子

// 首先 定义一个注册异常类  RegisterException  --->业务逻辑异常类
public class RegisterException extends RuntimeException {
    
    // 空参构造
    public RegisterException(){}
    
    // 有参构造
    public RegisterException(String message) {
        super(message);
    }
}

public class Demo {
    // 使用数组模拟数据库 已存在多个账户名称
    public static String[] names = {"白菜","萝卜","哒哒哒"};
    
    public static void main(String[] args) {
        // Scanner
        Scanner scan = new Scanner(System.in);
        String name = scan.next();   
        // 校验账户是否已被注册过
       try {
           // 可能会引发异常的代码
           checkName(name);// 如果没有发生异常,就代表注册成功
           System.out.println("注册成功!")
           names = Arrays.copyOf(names,names.length+1);
           names[names.length-1] = name;
       } catch (RegisterException e) {
          // 异常的处理逻辑
           e.printStackTrace();
       }           
    }
     
    // 校验账户是否已被注册
    public static boolean checkName(String usernmae) throws RegisterException {
        for (String name : names) {
            if (name.equals(username)) {
                // 表明 名字已经注册过了,就抛出注册异常
                throw new RegisterException("亲,您的名字已经被注册了,再换个名字吧!");
            }
        }
        return true;
    }
}
原文地址:https://www.cnblogs.com/9080dlb/p/14141275.html