Java学习笔记【8】异常

news2024/11/26 0:56:26

在这里插入图片描述

  ⛵ ⛵ ⛵ ⛵ ⛵ 🚀 🚀 🚀 🚀 🚀
  大家好🤝,我是 👉老孙👈,未来学习路上多多关照 🤝 一个喜欢用 ✍️ 博客记录人生的程序猿 🙉,或许这是一件很有意义又有趣的事 📖 ⏰ 🌏
  🔥 🔥 🔥 🔥 🔥 ⭐ ⭐ ⭐ ⭐ ⭐

Java异常目录

    • 1、思维导图
    • 2、异常概述
    • 3、异常处理机制
    • 4、捕获异常 try-catch-finally
      • 4.1、try-catch-finally 使用说明
      • 4.2、处理运行时异常
      • 4.3、处理编译时异常
    • 5、声明抛出异常 throws
    • 6、抛出和捕获结合使用
    • 7、自定义异常 throw

请添加图片描述

Java学习笔记前期内容回顾
Java学习笔记【1】Java概述
Java学习笔记【2】JDK环境配置
Java学习笔记【3】第一个 Java 程序Hello World!
Java学习笔记【4】基础语法 - - 关键字、变量和数据类型、Scanner类
Java学习笔记【5】基础语法 - - 运算符 和 运算规则
Java学习笔记【6】基础语法 - - 数组、流程控制和进制
待更新…

请添加图片描述

1、思维导图

在这里插入图片描述

2、异常概述

异常:在Java语言中,将程序执行中发生的不正常情况称为异常 (开发过程中的语法错误和逻辑错误不是异常)。

异常分类:

  • Error:Java虚拟机无法解决的严重问题,一般不编写针对性的代码进行处理。
    • 如:JVM系统内部错误、资源耗尽等严重情况、StackOverflowError堆栈溢出等
  • Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:空指针异常、试图读取不存在的文件、数组角标越界…
    • 编译时异常:是指编译器要求必须处置的异常,即程序在运行时由于外界因素造成的一般性异常。编译器要求Java程序必须捕获或声明所有编译时异常。对于这类异常,如果程序不处理,可能会带来意想不到的结果。
    • 运行时异常:是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。java.lang.RuntimeException 类及它的子类都是运行时异常。比如:除数为0,数组下标越界等;对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。

对于异常一般有两种解决方法:

  • 终止程序的运行
  • 编写程序时就考虑到错误的检测、错误消息的提示,以及错误的处理:捕获异常声明抛出异常自定义异常

Java异常处理机制:捕获异常声明抛出异常

3、异常处理机制

在编写程序时,经常要在可能出现错误的地方加上检测的代码,如进行x/y运算时,要检测分母为0,数据为空,输入的不是数据而是字符等。过多的if-else分支会导致程序的代码加长、臃肿,可读性差。因此采用异常处理机制。

Java异常处理Java采用的异常处理机制,是将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁、优雅,并易于维护。

异常处理的2种方式:

  • 方式一:try-catch-finally(直接捕获处理掉)
  • 方式二:throws + 异常类型(抛出交给调用者处理)

Java提供的是异常处理:抓抛模型

  • 过程一:“抛”
    • 程序在执行过程中如果出现异常,就会在异常代码处生成一个对应异常类的对象,并将此对象抛出(throw);一旦抛出对象以后,其后的代码就不再执行。
    • 关于异常对象的产生:
      • 系统自动生成的异常对象
      • 手动的生成一个异常对象,并抛出(throw)
  • 过程二:“抓”
    • 可以理解为异常的处理方式:① try-catch-finally ② throws

4、捕获异常 try-catch-finally

捕获异常过程:在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型去catch中进行匹配。一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理。如果有finally的情况下先执行finally中的语句,然后继续执行其后的代码。

4.1、try-catch-finally 使用说明

try{…}语句块:

  • 捕获异常的第一步将可能出现异常的代码放在try语句块中
  • 在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配。

在catch语句块中是对异常对象进行处理的代码

  • 每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。
  • 如果明确知道产生的是何种异常,可以用该异常类作为catch的参数;也可以用其父类作为catch的参数。比如: 可以用 ArithmeticException 类 作为参数的地方,就可以用RuntimeException类作为参数,或者用所有异常的父类Exception类作为参数。但不能是与ArithmeticException类无关的异常,如NullPointerException(catch中的语句将不会执行)。
  • catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓。
  • catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面;否则报错。

finally语句块:是可选的

  • 一定会执行的代码,即使catch中又出现异常了,try中有return语句,catch中有return语句等情况。
  • 像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的释放。此时的资源释放,就需要声明在finally中。
try{
...... // 可能产生异常的代码
}
catch( 异常类型1 变量名1 ){
...... // 当产生异常类型1时的处置措施
}
catch( 异常类型2 变量名1 ){
...... // 当产生异常类型2时的处置措施
}
...
finally{
...... //无论是否发生异常,一定会执行的代码【可选】
}
// 获取异常信息,返回字符串
System.out.println(e.getMessage());
// 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
e.printStackTrace();

4.2、处理运行时异常

处理运行时异常 RuntimeException

  • 常见运行时异常有:数学运算异常(如0位除数)、类型转换异常、空指针异常、数字格式异常、数组或字符下标越界异常
  • 这些类的异常的特点是:即使没有使用try和catch捕获,Java自己也能捕获,并且编译通过(但运行时会发生异常使得程序运行终止)
  • 开发中,由于运行时异常比较 常见,所以我们 通常就不针对运行时异常编写try-catch-finally
public class IndexOutException {
    public static void main(String[] args) {
        String[] arr = {"aaa", "bbb", "ccc"};
        try {
            System.out.println(arr[3]);
            System.out.println("try...");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组角标越界!");
        }
        System.out.println("方法执行结束...");
    }
}

4.3、处理编译时异常

处理编译时异常:则必须捕获,否则编译错误。

  • 常见编译时异常有:IO异常、数据库访问异常、指定类不存在异常等
  • 使用try-catch-finally处理编译时异常,使得程序在编译时就不再报错,但是运行时仍可能报错。相当于我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现,转化为运行时异常。
  • try-catch-finally结构可以嵌套
// 将工程路径下的test.txt文件打印到控制台
public class IOExceptionTest {
    public static void main(String[] args) {
        try {
            FileInputStream in = new FileInputStream("test.txt");
            int len;
            len = in.read();
            while (len != -1) {
                System.out.print((char) len);
                len = in.read();
            }
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println(e);
        } finally {
            System.out.println("执行其它语句...");
        }
    }
}
public void testDelete() {
    Connection conn = null;
    Statement statement = null;
    try {
        // 注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 获取连接对象
        conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");
        // 获取执行sql语句的对象
        statement = conn.createStatement();
        // sql语句
        String sql = "delete from student where id = 6";
        // 发送sql
        int i = statement.executeUpdate(sql);
        System.out.println("受影响的条数:" + i);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭连接
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

5、声明抛出异常 throws

如果一个方法中的语句执行时可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。(由JVM来处理,即默认异常操作,将会在出现异常处,终止程序运行,并返回异常栈内信息)

在方法声明中用throws语句可以声明抛出异常的列表(可以声明多个的异常),throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。

public void method(String str) throws 异常A,异常B,... { 方法体 }

throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。

public void readFile(String file) throws FileNotFoundException{
    ...
    // 读文件的操作可能产生FileNotFoundException类型的异常
    FileInputStream fis = new FileInputStream(file);
    ...
}
public void readFile(String file) throws IOException {
    ...
    FileInputStream fis = new FileInputStream(file);
    ...
}

重写方法不能抛出比被重写、方法范围更大的异常类型。

  • 在多态的情况下, 一般对methodA()方法的调用异常的捕获按父类声明的异常处理。
public class A {
    public void methodA() throws IOException {...} 
}

public class B1 extends A {
    public void methodA() throws FileNotFoundException {...}
}
    										
public class B2 extends A {
    //报错
    public void methodA() throws Exception {...} 
}

6、抛出和捕获结合使用

为保证程序正常执行,代码必须对可能出现的异常进行处理,需要 try-catch-finally 和 throws 结合使用。

注意:异常抛出给调用者,最终需在main()方法中处理。
在这里插入图片描述

举例:将工程路径下的test.txt文件打印到控制台

public class IOExceptionThrows {
    public static void main(String[] args) {
        IOExceptionThrows readFileTest = new IOExceptionThrows();
        try {
            readFileTest.readFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 抛出readFile()产生的异常,交给调用者main()处理
    public void readFile() throws IOException {
        FileInputStream in = new FileInputStream("test.txt");
        int b = in.read();
        while (b != -1) {
            System.out.print((char) b);
            b = in.read();
        }
        in.close();
    }
}
// 首先要生成异常类对象,然后通过throw语句实现抛出操作(提交给Java运行环境)。
IOException e = new IOException();
throw e;
// 可以抛出的异常必须是Throwable或其子类的实例。下面的语句在编译时将会产生语法错误:
throw new String("want to throw");

7、自定义异常 throw

JDK中定义了大量的异常可以描述异常情况,但在开发中会出现特殊的问题,为了解决这个问题,Java允许用户自定义异常;抛出异常 thow:当程序查到一个错误后,创建一个适当类型异常的实例并抛出它。

  • 一般地,用户自定义异常类都是RuntimeException的子类
  • 如何自定义异常类:需要编写几个重载的构造器、提供serialVersionUID、继承于现有的异常结构。
  • 用户自己的异常类 必须继承Throwable类或其子类的实例
  • 自定义异常最重要的是异常类的名字,当异常出现时,可以根据名字判断异常类型。
// 举例:人数注册
public class MyExceptionTest {
    public void register(int num) throws MyException {
        if (num < 0) {
            //出现异常时:创建自定义的异常类的实例
            throw new MyException("人数为负值,不合理", 500);
        } else {
            System.out.println("登记成功,人数为" + num);
        }
    }

    public void manager() {
        try {
            register(-1);
        } catch (MyException e) {
            System.out.println("登记失败,出错类型" + e.getId() + "\n" + e.getMessage());
        }
        System.out.print("本次登记操作结束");
    }

    public static void main(String args[]) {
        MyExceptionTest t = new MyExceptionTest();
        t.manager();
    }
}

// 自定义异常类
public class MyException extends Exception {

    static final long serialVersionUID = 13465653435L;
    
    private int id;

    public MyException(String message, int id) {
        super(message);
        this.id = id;
    }

    public int getId() {
        return id;
    }

}

在开发中自定义异常类一般继承异常类后重新一下构造方法即可,然后交给全局异常处理器。

// 举例:springboot项目实现用户下单的业务
@Transactional
public void submit(Orders orders) {
    ...
    // 防止购物车为空时点击下单
    if (shoppingCarts == null || shoppingCarts.size() == 0) {
        throw new CustomException("购物车为空,不能下单!");
    }
    ...
}

// 自定义异常类:CustomException
public class CustomException extends RuntimeException{
    public CustomException(String message) {
        super(message);
    }
}

// 全局异常处理器
@Slf4j
@ResponseBody // 返回JSON数据
@RestControllerAdvice
public class GlobalExceptionHandler {
   
     /**
     * 处理CustomException自定义业务异常
     */
    @ExceptionHandler(CustomException.class)
    public R<String> exceptionHandler(CustomException ex){
        return R.error(ex.getMessage());
    }
}

总结:
在这里插入图片描述


世界上最遥远的 距离,是我在 if 里你在 else 里,似乎一直相伴又永远分离;

世界上最痴心的 等待,是我当 case 你是 switch,或许永远都选不上自己;

世界上最真情的 相依,是你在 try 我在 catch。无论你发神马脾气,我都默默承受,静静处理。到那时,再来期待我们的 finally



😜 相 见 就 是 【 猿 分 】 🐒
.
👀 感谢您阅读完此文章 👀
.
❌ 如果文章中有错误的地方请指正 ✔️
.
✏️ 此文章参考尚硅谷教程笔记、Java相关书籍和个人学习经验总结的Java后端学习笔记 ⭐️
.
❓ 希望能够对你有所帮助 🎯
.
🔗 欢迎 【关注】【评论】【点赞】🚩
.
💪 感谢支持,一起加油,共同进步 🏃

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/116079.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python遥感图像处理应用篇(二十七):Python绘制遥感图像各波段热力图(相关系数矩阵)(续)

续-https://soderayer.blog.csdn.net/article/details/125757807 上一篇中使用csv文件计算的相关系数热力图,本篇我们直接使用遥感图像来计算图像波段之间的相关系数。 方法一:已有软件ENVI计算 实际上,目前已有的软件,如ENVI就可以直接计算图像波段之间的相关系数,该工…

【高精度定位】关于GPS、RTK、PPK三种定位技术的探讨

高精度定位通常是指亚米级、厘米级以及毫米级的定位&#xff0c;从市场需求来看&#xff0c;定位的精度越高往往越好。“高精度、低成本”的定位方案无疑将是未来市场的趋势。 在物联网时代&#xff0c;大多数的应用或多或少都与位置服务相关联&#xff0c;尤其是对于移动物体而…

深入理解MySQL——分库分表种类与原则

分库分表的种类 首先说明&#xff0c;这里所说的分库分表是指把数据库中数据物理地拆分到多个实例或多台机器上去&#xff0c;而不是MySQL原生的Partitioning。 这里稍微提一下Partitioning&#xff0c;这是MySQL官方版本支持的&#xff0c;在本地针对表的分区进行操作&#…

[Flask]各种子功能的实现

一、标准Flask架构搭建 ①config.py 新建一个文件config.py&#xff0c;在其中进行参数初始化&#xff0c;再使用下面代码加载到app.py&#xff08;主程序&#xff09;中 import config app.config.from_object(config) #由config.py初始化 ②exts.py 用于放置扩展模块&a…

(二十四)Vue之props配置项

文章目录props基本使用props的数组形式props的对象形式检测类型检测类型 其他验证Vue学习目录 上一篇&#xff1a;&#xff08;二十三&#xff09;Vue之ref属性 props props 可以是数组或对象&#xff0c;用于让组件接收外部传过来的数据 约定props是只读的&#xff0c;Vue…

开源 高性能 云原生!时序数据库 TDengine 上线亚马逊Marketplace

近日&#xff0c;涛思数据旗下开源、高性能、云原生的时序数据库&#xff08;Time Series Database&#xff0c;TSDB&#xff09;TDengine 成功上线亚马逊云科技 Marketplace&#xff0c;为用户提供了更加丰富的订阅渠道。 TDengine 是针对时序数据特点研发和优化的数据库解决方…

CentOS8 Elasticsearch8.x 安装遇到的问题解决汇总

报错清单 启动报错&#xff1a;ERROR: Elasticsearch exited unexpectedly curl测试报错&#xff1a;curl: (52) Empty reply from server 报错解决 启动报错 起因 使用archive方式安装elasticsearch后&#xff0c;在目录中运行./bin/elasticsearch报错如下&#xff1a; 原…

第二十七章 数论——快速幂与逆元

第二十七章 快速幂与扩展欧几里德算法一、快速幂1、使用场景2、算法思路&#xff08;1&#xff09;二进制优化思想&#xff08;2&#xff09;模运算法则3、代码实现&#xff08;1&#xff09;问题&#xff08;2&#xff09;代码二、快速幂求逆元1、什么是逆元&#xff1f;&…

结构体位段问题

每一位勇敢努力的少年&#xff0c;必将不负众望&#xff01; 什么是位段 位段的详细解释 位段其实也是一种结构体的类型 1.位段的成员是 int ,short int unsigned int , signed int , short , char 类型 2.位段的成员名后有一个冒号和一个数字 看一个例子&#xff1a; st…

通过静态LSP、LDP LSP、MPLS TE三种方式实现总部与分支的互通

一、静态LSP 特点&#xff1a;类似静态路由&#xff0c;简单易用&#xff0c;手动建立lsp&#xff0c;定制转发路径&#xff0c;无需控制报文&#xff0c;资源消耗少。 缺点&#xff1a;不适合大型复杂拓扑&#xff0c;不能根据网络变化而动态调整&#xff0c;需要管理员手动调…

【jprofiler应用-oom原因定位】

1.安装jprofiler jprofiler_windows-x64_11_0_2.exe 2.使用KeyGen.exe生成注册码然后输入 3.idea中安装jprofiler插件 File-->Setting-->Plugins 搜索jprofiler插件然后安装 4.以一个内存溢出的程序为例子进行分析(一直分配内存&#xff0c;List容器引用着Student导致…

医疗产品设计的新趋势

随着个人健康和医疗数据技术的发展&#xff0c;消费者可以选择更多的方法来跟踪和管理他们的健康状况&#xff0c;因此医疗产品开始转向更多的健康预防领域。医疗器械设计公司认为&#xff0c;随着医疗产品设计从医疗产品转向家庭&#xff0c;医疗产品的设计需要考虑更多的新问…

【HTML+CSS+JavaScript】实现简单网页版的飞机大战

文章目录【HTMLCSSJavaScript】实现简单网页版的飞机大战一. HTML部分代码二. CSS部分代码三. JavaScript部分代码四. 完整的代码和图片获取【HTMLCSSJavaScript】实现简单网页版的飞机大战 本文分享的是键盘版飞机大战的代码&#xff0c;且文章末尾有惊喜。 效果图&#xff1a…

前端食堂技术周刊第 64 期:Node.js 19、Interop 2022、SvelteKit 1.0、2022 Web 性能回顾、最流行的 Node.js

美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;冰糖雪梨 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 本期摘要 Node.js 19 的新特性Interop 2022 年终更新SvelteKit 1.02022 Web 性能回…

Python爬虫学习第十二天---scrapy学习

Python爬虫学习第十二天—scrapy学习 一、scrapy的概念和流程 1、scrapy概念 Scrapy是一个Python编写的开源网络爬虫框架&#xff0c;它是一个被设计用于爬取网络数据、提取结构性数据的框架。Scrapy文档地址&#xff1a;http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/…

采用抓包的方式逆向获得谷歌翻译的API

文章目录最开始的尝试2022.12.26谷歌翻译API相关信息发送网址提交的数据不过不出意外的失败了实验去掉参数去掉Headers代码对返回结果进行解析完整代码最开始的尝试 谷歌的翻译API老是发生变化&#xff0c;我们需要自己动手来找到谷歌的翻译API&#xff0c;这样才是最稳妥的解决…

个人博客系统(前后端分离)

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、项目简介二、项目效果三、项目实现1. 软件开发的基本流程2. 博客系统 需求分析3. 博客系统 概要设计4. 创建maven项目5. 编写数据库操作的代码四、项目代码总结普通小孩也要热爱生活&#xff01; 一、项目简介 …

Mac 音频转换器推荐 DRmare Audio Converter、Audi Free Auditor

Mac 音频转换器推荐 DRmare Audio Converter、Audi Free Auditor 给大家推荐两款 Mac 上的音频转换器&#xff0c;这两款转换器都可以转换苹果音乐&#xff0c;iTunes歌曲或者一些常规的音轨到MP3, FLAC, WAV, M4A, AAC格式等等&#xff0c;转换后我们就可以在所有的设备和播放…

stm32f407VET6 系统学习 day06 窗口看门狗, IIC 通信协议

1.独立看门狗&#xff0c;与窗口看门狗的差别 1. 差别1 &#xff1a; 窗口看门狗&#xff0c; 有上限 0x7F&#xff0c; 有下限 0x40 &#xff0c;&#xff0c; 独立看门狗只有下限 0 2. 差别2&#xff1a; 时钟源不同&#xff0c; 独立看门狗&#xff1a;LSI 窗口…

【iMessage苹果推群发】苹果相册推它由pushchatkey.pem和pushchatcert.pem作为单独的文件使用

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…