JAVA第十一学:认识异常

1.异常的介绍

1.1 异常的概念

在Java中,将程序执行过程中 发生的不正常行为 称为异常。


java中不同类型的异常 ,都有与其对应的类来进行描述


1.2 异常的体系结构

1.3 异常的分类




2.异常的处理

异常处理的核心思想 就是 EAFP

EAFP: 先操作,遇到问题再处理,事后认错型。"It's Easier to Ask Forgiveness than Permission" 事后获取原谅比事前获取许可更容易

优势:正常 流程和错误 流程是分离开的, 程序员更关注正常流程,代码更清晰,容易理解代码。

在Java中,异常处理主要的5个关键字throw、try、catch、final、throws。

2.1 抛出--throw 与 捕获--try-catch

在编写程序时,如果程序中出现错误 ,此时就需要将错误的信息告知给调用者,比如:参数检测。

在Java中,可以借助 throw 关键字,抛出一个指定的异常对象,将错误信息告知给调用者。具体语法如下:


异常的捕获 ,也就是异常的具体处理方式 ,主要有两种异常声明 throws 以及try-catch捕获处理

处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想 处理该异常,此时就可以借助 throws 将异常抛给方法的调用者 来处理。即当前方法不处理异常,提醒方法的调用者处理异常。

throws 对异常并没有真正处理 ,而是将异常报告给抛出异常方法的调用者 ,由调用者 处理。如果真正要对异常进行处理,就需要try-catch






注意事项

(1)try块内 抛出异常位置之后的代码将不会被执行

(2)如果抛出异常类型catch 时异常类型不匹配 ,即异常不会被成功捕获 ,也就不会被处理 ,继续往外抛(方法的调用者 ),直到 JVM 收到后中断程序----异常是按照类型来捕获的。

(3)try中可能会抛出多个 不同的异常 对象,则可以用多个 catch 来捕获 ----即多种异常,多次捕获(try-catch尽量一一对应)。

(4)如果多个异常处理方式完全相同, 也可以合并到同一个 catch 中

(5)如果异常 之间具有父子 关系,catch中一定是子类异常在前父类异常在后,否则语法错误。

(6)可以通过一个 catch 捕获所有的异常 ,即多个异常,一次捕获(不推荐)。

由于 Exception 类所有异常类的父类, 因此可以用这个类型表示捕捉所有异常

2.2 finally

在写程序时,有些特定的代码,不论程序是否发生异常,都需要执行 ,比如程序中打开的资源:网络连接、数据库 连接、IO流 等,在程序正常或者异常退出时,必须要对资源进进行回收 。另外,因为异常会引发程序的跳转,可能导致有些语句执行不到,finally就是用来解决这个问题的。

问题:既然 finally 和 try-catch-finally 后的代码都会执行,那为什么还要有finally呢?

对于某些程序(代码),如果正常输入,成功接收输入后程序就返回了,try-catch-finally之后的代码根本就没有执行 ,即输入流就没有被释放,造成资源泄漏。

注意:finally 中的代码一定会执行的,一般在 finally 中进行一些资源清理的扫尾工作。

finally 执行的时机是在方法返回之前 (try 或者 catch 中如果有return, 会在这个 return 之前执行 finally)

但是如果 finally 中也存在 return 语句, 那么就会执行 finally 中的 return , 从而不会执行try 中原有的 return。

一般我们不建议在 finally 中写 return (被编译器当做一个警告).

2.3 异常处理流程总结

3.自定义异常类

模拟一个登录场景

java 复制代码
import java.util.Scanner;

class UsernameError extends Exception {
    public UsernameError(String message) {
        super(message);
    }
}

class PasswordError extends Exception {
    public PasswordError(String message) {
        super(message);
    }
}

public class Test {
    private static void login() throws UsernameError, PasswordError {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名: ");
        String username = scanner.next();
        System.out.println("请输入密码: ");
        String password = scanner.next();

        // 验证用户输入的用户名和密码是否正确.
        if (!username.equals("admin")) {
            throw new UsernameError("用户名错误");
        }
        if (!password.equals("123456")) {
            throw new PasswordError("密码错误");
        }
        System.out.println("登录成功");
    }

    public static void main(String[] args) throws PasswordError, UsernameError {
        // 模拟一个登录的场景
        login();
    }
}
相关推荐
沐浴露z1 小时前
如何应对服务雪崩?详解 服务降级与服务熔断
java·微服务
毕设源码-邱学长1 小时前
【开题答辩全过程】以 基于JavaScript的图书销售网站为例,包含答辩的问题和答案
开发语言·javascript·ecmascript
liwulin05061 小时前
【JAVA】AES加密
java
阿宁又菜又爱玩2 小时前
Maven基础知识
java·maven
S***q3772 小时前
【Springboot】@Autowired和@Resource的区别
java·spring boot·mybatis
老王熬夜敲代码2 小时前
泛型编程的差异抽象思想
开发语言·c++·笔记
南部余额2 小时前
SpringBoot自定义场景启动器
java·spring boot·场景启动器
p***s912 小时前
【SpringBoot】日志文件
java·spring boot·spring