处理异常不再困难-try-catch-finally和throw语句详解

news2024/11/28 16:45:41

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在软件开发过程中,代码经常会出现各种问题,例如空指针、数组越界等等。在这些情况下,如果不进行处理,程序就会崩溃,严重影响用户体验。而处理这些异常是开发者必须要掌握的技能之一。

  Java中提供了try-catch-finally和throw语句来处理异常。本文将详细介绍这些语句的使用方法,并通过实际案例演示其应用场景及优缺点分析。

摘要

本文主要涉及以下几个方面:

  1. try-catch-finally和throw语句的基本语法和使用方法。

  2. 源代码解析,通过实例演示其应用场景。

  3. 对try-catch-finally和throw语句的优缺点进行分析。

  4. 类代码方法介绍。

  5. 测试用例(以main函数写法为准)。

正文

简介

  Java中的异常分为两种类型:受检异常(checked exception)和非受检异常(unchecked exception)。其中,受检异常是在编译时就能检测到的异常,必须要进行处理。而非受检异常是在运行时才能检测到的异常,可以进行处理也可以不进行处理。

  Java中使用try-catch-finally和throw语句来处理异常。其中,try-catch-finally语句用于捕获异常并进行处理,而throw语句用于抛出异常。下面将详细介绍这些语句的使用方法。

源代码解析

try-catch-finally语句

  try-catch-finally语句用于捕获异常并进行处理。其基本语法如下:

try {
    // 可能会抛出异常的代码块
} catch (异常类型1 异常变量1) {
    // 异常处理代码1
} catch (异常类型2 异常变量2) {
    // 异常处理代码2
} finally {
    // 无论是否抛出异常,都会执行的代码块
}

  在try语句块中,开发者可以编写可能会抛出异常的代码。如果在try语句块中抛出了异常,程序会跳转到相应的catch语句块进行异常处理。如果没有抛出异常,程序会跳过catch语句块,直接执行finally语句块。

  catch语句块可以有多个,并且需要按照从上到下的顺序进行排列。如果抛出的异常类型与catch语句块中的异常类型匹配,则会执行对应的catch语句块进行异常处理。如果抛出的异常类型与所有catch语句块中的异常类型均不匹配,则会向上抛出异常。

  finally语句块中的代码无论是否抛出异常,都会被执行。通常将一些必须要执行的代码放在finally语句块中,例如关闭文件、关闭网络连接等等。

  下面通过实例演示try-catch-finally语句的应用场景。

public class MyFileUtils {
    public static void copyFile(String src, String dest) {
        FileInputStream input = null;
        FileOutputStream output = null;
        try {
            input = new FileInputStream(src);
            output = new FileOutputStream(dest);
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = input.read(buffer)) != -1) {
                output.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  在上面的代码中,我们封装了一个copyFile方法,用于将源文件复制到目标文件中。在方法中,我们使用了try-catch-finally语句来进行异常处理。

  在try语句块中,我们打开了源文件和目标文件,并使用一个byte数组来进行文件的读写操作。在catch语句块中,我们对抛出的IOException异常进行了简单的处理,并打印了异常堆栈信息。在finally语句块中,我们关闭了文件流,以确保资源被正确释放。

  根据如上代码分析可得:
  该代码定义了一个 MyFileUtils 类,其中包含了一个用于复制文件的静态方法 copyFile。该方法接收两个字符串参数:源文件路径 src 和目标文件路径 dest

  在方法中,首先创建了两个文件流对象 inputoutput,用于读取和写入文件。然后使用 FileInputStreamFileOutputStream 类传入对应的文件路径来初始化这两个流对象。

  接下来,使用一个 byte 类型的数组作为缓冲区,以便分段读取源文件的内容。在 while 循环中,每次从输入流中读取一定数量的数据到缓冲区中,然后将缓冲区中的数据写入到输出流中。

  最后在 finally 块中对输入流和输出流进行关闭操作,以释放资源。

  值得注意的是,在方法中使用了 try-catch 块捕获了 IOException 异常,在出现异常时会打印异常信息,但并不会对异常进行处理。如果在使用该方法时出现异常,需要根据具体情况进行处理。

throw语句

  throw语句用于抛出异常。其基本语法如下:

throw 异常对象;

  在使用throw语句时,需要先定义一个异常类,例如:

package com.example.javase.se.controlProgram;

/**
 * @Author ms
 * @Date 2023-11-13 23:03
 */
public class MyException extends Throwable {

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

}

  在上面的代码中,我们定义了一个MyException类,它继承自Exception类,并提供了一个带有字符串参数的构造函数。

  根据如上代码分析可得:
  这是一个自定义异常类MyException,它继承自Throwable类,用于创建特定的异常。通过传入异常信息的构造方法来创建MyException实例。在程序运行时,当需要抛出MyException时,可以通过throw new MyException(“异常信息”)语句来抛出。在处理异常时,可以使用try-catch语句捕获并处理MyException异常。

  下面通过实例演示throw语句的应用场景。

public void divide(int a, int b) throws MyException {
    if (b == 0) {
        throw new MyException("除数不能为0");
    } else {
        System.out.println(a / b);
    }
}

  在上面的代码中,我们定义了一个divide方法,用于进行除法运算。如果除数为0,则会抛出一个MyException异常。否则,方法会计算出商并进行输出。

  在上面的代码中,我们使用了throws关键字来声明方法可能会抛出MyException异常。这是因为MyException是一种受检异常,在使用时必须进行处理。

  根据如上代码分析可得:
  该方法用于进行两个整数的除法运算,其中a为被除数,b为除数。在执行除法运算之前,代码进行了一个判断,当除数为0时,抛出自定义异常MyException,异常信息为“除数不能为0”。如果除数不为0,则执行除法运算并输出结果。如果在执行过程中抛出了MyException异常,该异常会被抛到方法的调用处,由调用方来处理该异常。

应用场景案例

  在Java中,try-catch-finally和throw语句的应用场景非常广泛。下面将通过实际案例演示它们的应用场景。

文件操作

  在Java中,进行文件操作时经常会出现I/O异常,例如文件不存在、文件读写错误等等。此时,我们通常会使用try-catch-finally语句来进行异常处理。下面是一个例子。

public class MyFileUtils {
    public static void copyFile(String src, String dest) {
        FileInputStream input = null;
        FileOutputStream output = null;
        try {
            input = new FileInputStream(src);
            output = new FileOutputStream(dest);
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = input.read(buffer)) != -1) {
                output.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  在上面的代码中,我们封装了一个copyFile方法,用于将源文件复制到目标文件中。在方法中,我们使用了try-catch-finally语句来进行异常处理。

  在try语句块中,我们打开了源文件和目标文件,并使用一个byte数组来进行文件的读写操作。在catch语句块中,我们对抛出的IOException异常进行了简单的处理,并打印了异常堆栈信息。在finally语句块中,我们关闭了文件流,以确保资源被正确释放。

  根据如上代码分析可得:
  这是一个 Java 类,名为 MyFileUtils。

  其中有一个静态方法 copyFile,该方法接受两个字符串参数,分别为源文件路径和目标文件路径。该方法的作用是将源文件复制到目标文件。

  在该方法中,使用了 FileInputStream 和 FileOutputStream 对象来读写文件。使用了一个 byte 数组作为缓存区,每次从 FileInputStream 中读取数据到缓存区,再将缓存区的数据写入 FileOutputStream。

  在 try-catch 块中处理了可能出现的 IOException 异常。在 finally 块中关闭了 FileInputStream 和 FileOutputStream 对象,确保资源释放。

数组操作

  在Java中,进行数组操作时经常会出现数组越界异常,例如访问不存在的数组下标等等。此时,我们通常会使用try-catch语句块来进行异常处理。下面是一个例子。

public class MyArrayUtils {
    public static int getElement(int[] array, int index) {
        try {
            return array[index];
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
            return -1;
        }
    }
}

  该代码演示了try-catch-finally语句的一个典型应用场景:文件操作。在该例子中,我们封装了一个copyFile方法用于将源文件复制到目标文件。在try语句块中,我们打开了源文件和目标文件,并使用一个byte数组来进行文件的读写操作。如果在读写过程中出现IOException异常,就会跳转到catch语句块中进行异常处理。在catch语句块中,我们对抛出的异常进行了简单的处理,并打印了异常堆栈信息。在finally语句块中,我们关闭了文件流,以确保资源被正确释放。

  此外,还演示了另一个典型应用场景:数组操作。在该例子中,我们封装了一个getElement方法用于获取数组中指定下标的元素。我们使用了try-catch语句块来进行异常处理。如果访问的下标越界,就会跳转到catch语句块中进行异常处理。在catch语句块中,我们对抛出的异常进行了简单的处理,并打印了异常堆栈信息,同时返回-1作为方法的返回值。

  总的来说,try-catch-finally和throw语句在Java中的应用场景非常广泛,可以用于处理各种异常情况,保证程序的正确性和稳定性。

优缺点分析

try-catch-finally语句的优缺点

优点
  1. 适用范围广:try-catch-finally语句可以用于处理各种受检、非受检异常,在Java中应用广泛。
  2. 减少程序崩溃率:通过try-catch-finally语句,可以对抛出的异常进行有效处理,从而避免程序崩溃。
  3. 确保资源被释放:在finally语句块中,可以确保程序执行完后关闭资源,避免资源泄露问题。
缺点
  1. 程序可读性降低:过多的try-catch语句会让程序变得更加冗长,可读性降低。
  2. 可能会掩盖错误:如果catch语句块中的异常处理不当,可能会掩盖真正的错误,导致后续程序出现问题。

throw语句的优缺点

优点
  1. 可以抛出自定义异常:通过throw语句,开发者可以自定义异常类,并进行抛出。
  2. 规范异常处理:通过抛出异常,开发者可以引导程序执行指定的异常处理方法,避免程序崩溃。
缺点
  1. 只能抛出一个异常:throw语句只能抛出一个异常,如果需要抛出多个异常,则需要添加多个throw语句。
  2. 异常处理不当会影响程序性能:如果throw语句使用不当,可能会导致程序性能下降。

类代码方法介绍

try-catch-finally语句

try {
    // 可能会抛出异常的代码块
} catch (异常类型1 异常变量1) {
    // 异常处理代码1
} catch (异常类型2 异常变量2) {
    // 异常处理代码2
} finally {
    // 无论是否抛出异常,都会执行的代码块
}

  在try语句块中,开发者可以编写可能会抛出异常的代码。如果在try语句块中抛出了异常,程序会跳转到相应的catch语句块进行异常处理。如果没有抛出异常,程序会跳过catch语句块,直接执行finally语句块。

  catch语句块可以有多个,并且需要按照从上到下的顺序进行排列。如果抛出的异常类型与catch语句块中的异常类型匹配,则会执行对应的catch语句块进行异常处理。如果抛出的异常类型与所有catch语句块中的异常类型均不匹配,则会向上抛出异常。

  finally语句块中的代码无论是否抛出异常,都会被执行。通常将一些必须要执行的代码放在finally语句块中,例如关闭文件、关闭网络连接等等。

throw语句

throw 异常对象;

  在使用throw语句时,需要先定义一个异常类。在抛出异常时,需要将异常对象作为参数传递给throw语句。当程序执行到throw语句时,会将异常对象抛出,进入异常处理过程。

测试用例

下面提供一些测试用例,供读者参考。

try-catch-finally语句

try {
    int a = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("除数不能为0");
} finally {
    System.out.println("程序执行完毕");
}

  在上面的代码中,我们使用了try-catch-finally语句来进行异常处理。在try语句块中,我们进行了一个除法运算,但是除数为0,会抛出ArithmeticException异常。在catch语句块中,我们对抛出的异常进行了处理。在finally语句块中,我们打印了一条语句,表示程序执行完毕。

throw语句

public static void printName(String name) throws MyException {
    if (name == null || name.isEmpty()) {
        throw new MyException("姓名不能为空");
    } else {
        System.out.println("姓名为:" + name);
    }
}

  在上面的代码中,我们定义了一个printName方法,用于打印姓名。在方法中,我们使用了throw语句来抛出一个MyException异常。如果传入的姓名为null或者空字符串,就会抛出该异常。如果传入的姓名不为空,就会打印该姓名。在方法签名中,我们使用throws关键字声明方法可能会抛出MyException异常。

  根据如上代码测试结果如下:

在这里插入图片描述
  根据如上代码分析可得:
  这是一个静态方法,方法名为printName,参数为一个String类型的name。方法中先判断传入的name是否为null或者空字符串,如果是,则抛出一个自定义的异常MyException,异常信息为“姓名不能为空”。如果name不为null且不为空,则输出“姓名为:”加上name的值。同时,这个方法声明了一个抛出MyException异常,表示调用该方法的代码可能会遇到这个异常,需要进行异常处理。

总结

  本文深入介绍了Java中异常处理相关的知识,主要包括try-catch-finally语句和throw语句的基本语法和使用方法。同时,通过实例演示和优缺点分析,阐述了它们的应用场景和优缺点。

  try-catch-finally语句作为Java中必不可少的异常处理语句,可以用于处理各种受检、非受检异常,在Java中应用广泛。通过try-catch-finally语句,可以对抛出的异常进行有效处理,从而避免程序崩溃。同时,在finally语句块中,可以确保程序执行完后关闭资源,避免资源泄露问题。但是,过多的try-catch语句会让程序变得更加冗长,可读性降低,如果catch语句块中的异常处理不当,可能会掩盖真正的错误,导致后续程序出现问题。

  throw语句可以用于抛出自定义异常,并引导程序执行指定的异常处理方法,避免程序崩溃。它的缺点是只能抛出一个异常,如果需要抛出多个异常,则需要添加多个throw语句。如果throw语句使用不当,可能会导致程序性能下降。

  最后,本文提供了一些测试用例供读者参考,希望能够对读者理解和掌握Java异常处理相关知识有所帮助。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

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

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

相关文章

《软件定义安全》之三:用软件定义的理念做安全

第3章 用软件定义的理念做安全 1.不进则退,传统安全回到“石器时代” 1.1 企业业务和IT基础设施的变化 随着企业办公环境变得便利,以及对降低成本的天然需求,企业始终追求IT集成设施的性价比、灵活性、稳定性和开放性。而云计算、移动办公…

《软件定义安全》之二:SDN/NFV环境中的安全问题

第2章 SDN/NFV环境中的安全问题 1.架构安全 SDN强调了控制平面的集中化,从架构上颠覆了原有的网络管理,所以SDN的架构安全就是首先要解决的问题。例如,SDN实现中网络控制器相关的安全问题。 1.1 SDN架构的安全综述 从网络安全的角度&…

算法训练营day04

一、24. 两两交换链表中的节点 题目链接:https://leetcode.cn/problems/swap-nodes-in-pairs/description/ 文章讲解:https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.h…

运维实用小脚本,登录即自动显示系统信息

今天给大家安利一个超级实用的Linux小技巧,让你每次登录终端时都能感受到满满的科技感和效率爆棚! 你是否厌倦了每次手动检查系统状态,像内存使用、CPU负载这些繁琐操作?别担心,一个小调整,让这一切自动化…

当我拿到百度文心智能体大赛top1后,我又开发了...

目录 一、写在前面 二、代码助手 三、关于智能体 四、写在后面 一、写在前面 在不久前结束的文心智能体大赛(第一期)中,我有幸凭借一款名为恋爱助手的智能体斩获了大赛的桂冠。这个成绩,既是对我努力的认可,也是对…

YOLOv8_obb的训练、验证、预测及导出[旋转目标检测实践篇]

1.旋转目标检测数据集划分和配置 从上面得到的images和labels数据还不能够直接训练,需要按照一定的比例划分训练集和验证集,并按照下面的结构来存放数据,划分代码如下所示,该部分内容和YOLOv8的训练、验证、预测及导出[目标检测实践篇]_yolov8训练测试验证-CSDN博客是重复的…

linux本地搭建apt源

使用apt-mirror搭建 1.安装 apt-get install apt-mirror2.编辑配置文件 vi /etc/apt/mirror.list修改下载目录 set_base_path 后面改为下载镜像的目录,同时删除前面#号 添加同步的源,建议用国内的,速度快,我这里用的阿里云的镜…

调查显示各公司在 IT 安全培训方面存在差距

网络安全提供商 Hornetsecurity 最近进行的一项调查显示,许多组织的 IT 安全培训存在严重缺陷。 这项调查是在伦敦举行的 Infosecurity Europe 2024 期间发布的,调查发现 26% 的组织没有为其最终用户提供任何 IT 安全培训。 这些调查结果来自世界各地的…

网页中生成ZIP文件,Zip 压缩、解压技术在 HTML5 浏览器中的应用

JSZip 是一款可以创建、读取、修改 .zip 文件的 javaScript 工具。在 web 应用中,免不了需要从 web 服务器中获取资源,如果可以将所有的资源都合并到一个 .zip 文件中,这时候只需要做一次请求,这样既减少了服务器的压力&#xff0…

mysql 更改数据存储目录

先停止 mysql :sudo systemctl start/stop mysql 新建新的目录, 比如 /mnt/data/systemdata/mysql/mysql_data sudo chown -R mysql:mysql /mnt/data/sysdata/mysql/mysql_data sudo chmod -R 750 /mnt/data/sysdata/mysql/mysql_data 更改mysql.cnf…

Hadoop3:MapReduce源码解读之Map阶段的FileInputFormat的切片原理(2)

Job那块的断点代码截图省略,直接进入切片逻辑 参考:Hadoop3:MapReduce源码解读之Map阶段的Job任务提交流程(1) 4、FileInputFormat切片源码解析 切片入口 获取切片 获取切片最大的Size和切片最小的Size 判断文件是…

【基于C++与OpenCV实现魔方图像识别和还原算法】施工总览图

文章目录 主要效果展示思维导图魔方还原算法 本系列博客长期更新,分为两大部分 OpenCV实现魔方六面识别 C编写科先巴二阶段还原算法实现三阶魔方的还原 主要效果展示 摄像头识别六面 3D图像构建,提供还原公式 动画演示还原过程 思维导图 魔方还原算法 参…

计算机组成原理复习笔记

前言 就是按照考试的题型写的总结 非常应试版 题型 一、进制转换 只考 十进制 二进制 十六进制 之间的相互转换 一个个看 (1)十进制 转其他 转二进制:除以2 从小到大取余数(0或1) 转十六进制 : 除以1…

【机器学习】机器学习引领AI:重塑人类社会的新纪元

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀机器学习引领AI 📒1. 引言📕2. 人工智能(AI)🌈人工智能的发展🌞应用领…

C# 界面控件中英切换

编程软件:VS 2015 需求:界面有两个按钮,点击可以将界面上所有控件进行不同语言的切换。 一共两种方案,个人认为第二种方案使用范围更广(这里以中英文切换为例)。 方案一:如图所示,建立两个资源文件 将所需控件的中英…

1.奖牌的数量

上海市计算机学会竞赛平台 | YACSYACS 是由上海市计算机学会于2019年发起的活动,旨在激发青少年对学习人工智能与算法设计的热情与兴趣,提升青少年科学素养,引导青少年投身创新发现和科研实践活动。https://www.iai.sh.cn/problem/447 题目描述 小爱获得了 𝑎a 枚金牌,…

windows10使用触控板、鼠标(magic trackpad)———附带BootCamp6驱动下载链接

文章目录 0 背景1 步骤1.1 下载1.2 解压1.3 安装驱动 参考 0 背景 最近在台式机(windows10系统)上使用mac设备,键盘magic keybord连上数据线就可以直接使用,但是触控板magic trackpad却不行,只有鼠标左键,…

Steam下载游戏很慢?一个设置解决!

博主今天重装系统后,用steam下载发现巨慢 500MB,都要下载半小时。 平时下载软件,一般1分钟就搞定了,于是大致就知道,设置应该出问题了 于是修改了,如下设置之后,速度翻了10倍。 如下&#x…

【Docker系列】跨平台 Docker 镜像构建:深入理解`--platform`参数

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

ChromaDB初探

探索ChromaDB 在当今数据驱动的世界中,随着人工智能和机器学习的广泛应用,如何高效地存储、检索和操作大量向量数据成为了一个关键问题。ChromaDB作为一种强大的向量数据库,正在为解决这一问题提供全新的解决方案。在这篇博客中,…