Java 异常

发布于:2025-06-01 ⋅ 阅读:(21) ⋅ 点赞:(0)


在这里插入图片描述

异常

  1. 异常:将程序执行过程中发生的不正常行为,异常也是一个类
  2. 程序出现异常后将不会继续执行
  3. 异常的分类:算术异常,空指针异常,数组越界异常

算术异常

在这里插入图片描述
空指针异常
在这里插入图片描述
数组越界异常
在这里插入图片描述

异常和错误

在这里插入图片描述

  1. 异常到底有多少个?它们之间的关系是什么?

异常分为运行时异常和编译时异常

运行时异常(非受查异常):运行时才能检测出来

编译时异常(受查异常):没进行运行前就能检测出来,比如clone(深浅拷贝)

在这里插入图片描述
在这里插入图片描述
2. RunTimeException以及其子类对应的异常都是运行时异常

异常的处理

  1. Java中用的是try catch来捕获异常

在这里插入图片描述
2. 如何让程序抛出异常?
抛出异常的方式有很多种:

  1. 某段程序触发(JVM抛出)

  2. 通过关键字throw抛出异常(手动抛出)

throw

在这里插入图片描述
throws,异常的声明,后面可以跟多个异常,用逗号隔开
如果在方法内出现了编译时异常,在方法的声明后面声明这个异常就不会报错,最后这个异常是交给JVM处理的

在这里插入图片描述
在这里插入图片描述
3. throws的处理逻辑:

在这里插入图片描述
4. 调用抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出,下图中这种异常是交给JVM处理的

在这里插入图片描述
5. 程序员自己处理的异常
在这里插入图片描述

JVM处理异常和自己处理异常

  1. 一旦交给JVM处理,程序就会到对应的异常处终止异常

  2. 自己用try catch捕获异常,并且捕获多个异常
    在这里插入图片描述
    在这里插入图片描述

  3. 捕获多个异常,虽然可以捕获多个异常,但是同一时刻只能抛出一个异常

  4. 多个异常的处理方式完全相同可以使用以下方式捕获

在这里插入图片描述
5. 父类的异常和子类的异常同时存在,可以用一个Exception捕获所有的异常(但是不推荐这样做)

在这里插入图片描述

  1. 此时是可以的子类捕获不到的异常,用父类来捕获

在这里插入图片描述
在这里插入图片描述

  1. 未正确捕获异常,直接报错

在这里插入图片描述
8. 正确捕获异常后不会影响后续代码的执行

在这里插入图片描述

finally

  1. 无论是否发生异常,finally都将被执行
public class test {
    public static void main(String[] args) {
        try{
            int[] array = {1,2,3};
            System.out.println(array[3]);
        }catch(ArrayIndexOutOfBoundsException e){
            e.printStackTrace();// 打印栈的痕迹
        }finally{
            System.out.println("111");
        }
        System.out.println("后续代码");
    }
}
  1. finally一定会被执行,finally中的代码会在return之前执行

在这里插入图片描述

  1. finally用来释放资源,Scanner也是一种资源,使用完之后需要close该资源,放在try括号中就不需要手动关闭了,可以把需要关闭的资源写在try的括号中

在这里插入图片描述
在这里插入图片描述

  1. 为什么一定要使用finally,在finally内部进行释放资源呢?
    如果是try中有return的话,不使用finally就会造成资源泄露,关闭资源写在finally之外

面试题

  1. throw和throws有什么区别?

throw是用来抛出异常的,throws是用来声明异常的,出现编译时异常,用throws来声明就不会报错了,但是是没有处理这个异常的

  1. finally中的语句一定会被执行吗?
    是的,一定会被执行

异常的处理流程

  1. 异常会沿着调用栈向上传递,比如func方法中出现了异常,那么调用它的main方法中可以写处理异常的逻辑,也可以在func方法中处理异常,如果没有处理就在func方法后面声明这个异常

在这里插入图片描述
2. 总结
在这里插入图片描述

自定义异常类

  1. 如果要写一个自定义异常,一定要继承一个异常,并且自定义异常都是继承Exception或者是RunTimeException的
    extends Exception 编译时异常(受查异常)
    extends RuntimeException 运行时异常(非受查异常)

  2. 例子:用户名和密码的登录

public class Test {
    private String userId = "一";
    private String  password = "010101";

    public void login(String userId,String password) {
    
            if(!this.userId.equals(userId)){
                System.out.println("用户名错误");
            }
            if(!this.password.equals(password)){
                System.out.println("密码错误");
            }
        System.out.println("登录成功");
    }
    public static void main(String[] args) {
        Test test = new Test();
        test.login("一","010101");
    }
}

上面密码和用户名都是正确的,不会抛出异常
用户名或者密码错误会抛出异常,需要写自定义异常,继承自Exception或者是RunTimeException

自定义异常类

//继承基类异常
//用户名异常
//这里继承的是受查异常
// 用户名异常
class UserIdException extends Exception{
    public UserIdException(String message){
        super(message);
    }
}
//密码异常
class PasswordException extends Exception{
        public PasswordException(String message){
            super(message);
        }
}

如果用户名或者密码不正确就会报出异常,在main方法中或者是login方法中捕获异常

class UserIdException extends Exception{
    public UserIdException(String message){
        super(message);
    }
}
class PasswordException extends Exception{
        public PasswordException(String message){
            super(message);
        }
}
public class Test {
    private String userId = "三三";
    private String  password = "060610";

    public void login(String userId,String password) {
        // 捕获异常
        try {
            if(!this.userId.equals(userId)){
                throw new UserIdException("用户名错误"+userId);
            }
            if(!this.password.equals(password)){
                throw new PasswordException("密码错误"+password);
            }
            //如果没有异常就会登录成功
            System.out.println("登录成功");
        }catch (UserIdException e){
            e.printStackTrace();
        }catch (PasswordException e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Test test = new Test();
        test.login("三三","060610");
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到