Java Catching and Handling Exceptions(二)

一、Try with resources语句

try with resources语句是声明一个或多个资源的try语句。资源是程序使用完后必须关闭的对象。try with resources语句确保在语句末尾关闭每个资源。任何实现java.lang.AutoCloseable的对象(包括实现java.io.Closeable的所有对象)都可以用作资源。
下面的示例从文件中读取第一行。它使用BufferedReader的实例从文件中读取数据。BufferedReader是一种资源,必须在程序完成后关闭:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

在本例中,try-with-resources语句中声明的资源是BufferedReader。声明语句出现在try关键字后面的括号中。在Java SE 7和更高版本中,类BufferedReader实现了接口Java.lang.AutoCloseable。由于BufferedReader实例是在try with resource语句中声明的,因此无论try语句是正常完成还是突然完成(作为方法BufferedReader.readLine()引发IOException的结果),它都将被关闭。
在JavaSE7之前,您可以使用finally块来确保关闭资源,无论try语句是正常完成还是突然完成。下面的示例使用finally块而不是try with resources语句:

static String readFirstLineFromFileWithFinallyBlock(String path)
                                                     throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        br.close();
    }
}

然而,在本例中,如果方法readLine()和close都抛出异常,则方法readFirstLineFromFileWithFinallyBlock()抛出从finally块抛出的异常;从try块引发的异常被抑制。相反,在示例readFirstLineFromFile()中,如果从try块和try with resources语句中抛出异常,则方法readFirst LineFrom()抛出从try区块抛出的异常;从try-with-resources块引发的异常被抑制。在JavaSE7和更高版本中,您可以检索被抑制的异常;有关详细信息,请参阅抑制的异常一节。
您可以在try-with-resources语句中声明一个或多个资源。下面的示例检索压缩文件zipFileName中打包的文件的名称,并创建包含这些文件名称的文本文件:

public static void writeToFileZipFileContents(String zipFileName,
                                           String outputFileName)
                                           throws java.io.IOException {

    java.nio.charset.Charset charset =
         java.nio.charset.StandardCharsets.US_ASCII;
    java.nio.file.Path outputFilePath =
         java.nio.file.Paths.get(outputFileName);

    // Open zip file and create output file with
    // try-with-resources statement

    try (
        java.util.zip.ZipFile zf =
             new java.util.zip.ZipFile(zipFileName);
        java.io.BufferedWriter writer =
            java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
    ) {
        // Enumerate each entry
        for (java.util.Enumeration entries =
                                zf.entries(); entries.hasMoreElements();) {
            // Get the entry name and write it to the output file
            String newLine = System.getProperty("line.separator");
            String zipEntryName =
                 ((java.util.zip.ZipEntry)entries.nextElement()).getName() +
                 newLine;
            writer.write(zipEntryName, 0, zipEntryName.length());
        }
    }
}

在本例中,try-with-resources语句包含两个由分号分隔的声明:ZipFile和BufferedWriter。当直接跟在它后面的代码块正常或由于异常而终止时,BufferedWriter和ZipFile对象的close()方法将按此顺序自动调用。请注意,资源的close方法是按其创建的相反顺序调用的。
下面的示例使用try with resources语句自动关闭java.sql.statement对象:

public static void viewTable(Connection con) throws SQLException {

    String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";

    try (Statement stmt = con.createStatement()) {
        ResultSet rs = stmt.executeQuery(query);

        while (rs.next()) {
            String coffeeName = rs.getString("COF_NAME");
            int supplierID = rs.getInt("SUP_ID");
            float price = rs.getFloat("PRICE");
            int sales = rs.getInt("SALES");
            int total = rs.getInt("TOTAL");

            System.out.println(coffeeName + ", " + supplierID + ", " +
                               price + ", " + sales + ", " + total);
        }
    } catch (SQLException e) {
        JDBCTutorialUtilities.printSQLException(e);
    }
}

本例中使用的资源java.sql.Statement是JDBC 4.1和更高版本API的一部分。
注意:try-with-resources语句可以像普通的try语句一样具有catch和finally块。在try-with-resources语句中,任何catch或finally块都在声明的资源关闭后运行。

二、Suppressed Exceptions

可以从与try-with-resources语句关联的代码块中引发异常。在示例writeToFileZipFileContents()中,可以从try块引发异常,并且当try with resources语句尝试关闭ZipFile和BufferedWriter对象时,可以从该语句引发多达两个异常。如果从try块引发异常,并且从try with resources语句引发一个或多个异常,则从try with resources.语句引发的那些异常将被抑制,并且该块引发的异常是由writeToFileZipFileContents()方法引发的异常。通过从try块引发的异常中调用Throwable.getSuppressed()方法,可以检索这些被抑制的异常。

三、实现自动关闭或可关闭接口的类

请参阅AutoCloseable和Closeable接口的Javadoc,以获取实现这两个接口之一的类的列表。Closeable界面扩展了AutoCloseable接口。Closeable接口的close()方法抛出IOException类型的异常,而AutoCloseble接口的closer()方法则抛出Exception类的异常。因此,AutoCloseable接口的子类可以覆盖close()方法的这种行为,以抛出专门的异常,如IOException,或者根本没有异常。

四、将所有内容放在一起

前面的部分描述了如何在ListOfNumbers类中为writeList()方法构造try、catch和finally代码块。现在,让我们遍历代码并研究可能发生的情况。
将所有组件放在一起时,writeList()方法如下所示。

public void writeList() {
    PrintWriter out = null;

    try {
        System.out.println("Entering" + " try statement");

        out = new PrintWriter(new FileWriter("OutFile.txt"));
        for (int i = 0; i < SIZE; i++) {
            out.println("Value at: " + i + " = " + list.get(i));
        }
    } catch (IndexOutOfBoundsException e) {
        System.err.println("Caught IndexOutOfBoundsException: "
                           +  e.getMessage());

    } catch (IOException e) {
        System.err.println("Caught IOException: " +  e.getMessage());

    } finally {
        if (out != null) {
            System.out.println("Closing PrintWriter");
            out.close();
        }
        else {
            System.out.println("PrintWriter not open");
        }
    }
}

如前所述,该方法的try块具有三种不同的退出可能性;这里有两个。

  1. try语句中的代码失败并引发异常。这可能是新FileWriter语句导致的IOException,也可能是for循环中错误的索引值导致的IndexOutOfBoundsException。
  2. 一切成功,try语句正常退出。

让我们看看在这两种退出可能性期间,writeList()方法中发生了什么。

1、场景1:发生异常

由于多种原因,创建FileWriter的语句可能会失败。例如,如果程序无法创建或写入所指示的文件,FileWriter的构造函数将引发IOException。
当FileWriter抛出IOException时,运行时系统立即停止执行try块;正在执行的方法调用未完成。然后,运行时系统开始在方法调用堆栈的顶部搜索适当的异常处理程序。在本例中,当IOException发生时,FileWriter构造函数位于调用堆栈的顶部。然而,FileWriter构造函数没有适当的异常处理程序,因此运行时系统检查方法调用堆栈中的下一个方法——writeList()方法。writeList()方法有两个异常处理程序:一个用于IOException,另一个用于IndexOutOfBoundsException。
运行时系统按照writeList()的处理程序在try语句之后出现的顺序来检查它们。第一个异常处理程序的参数是IndexOutOfBoundsException。这与引发的异常类型不匹配,因此运行时系统检查下一个异常处理程序-IOException。这与引发的异常类型匹配,因此运行时系统结束对适当异常处理程序的搜索。既然运行库已经找到了适当的处理程序,那么就执行该catch块中的代码。
在异常处理程序执行后,运行时系统将控制传递给finally块。finally块中的代码执行,而不管它上面捕获到什么异常。在这种情况下,FileWriter从未打开,也不需要关闭。在finally块完成执行后,程序继续执行finally模块之后的第一条语句。
这是ListOfNumbers程序的完整输出,在引发IOException时出现。 

Entering try statement
Caught IOException: OutFile.txt
PrintWriter not open

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探秘 AJAX:让网页变得更智能的异步技术(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

基于ssm计算机科学与技术学习网站的设计与开发论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本在校学习网站就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&am…

【MySQL】Sql优化之索引的使用方式(145)

索引分类 1.单值索引 单的意思就是单列的值&#xff0c;比如说有一张数据库表&#xff0c;表内有三个字段&#xff0c;分别是 id name numberNo&#xff0c;我给name 这个字段加一个索引&#xff0c;这就是单值索引&#xff0c;因为只有name 这一列是索引&#xff1b; 一个表…

【SpringBoot篇】基于Redis实现生成全局唯一ID的方法

文章目录 &#x1f354;生成全局唯一ID&#x1f339;为什么要生成全局唯一id&#x1f33a;生成全局id的方法✨代码实现 &#x1f354;生成全局唯一ID 是一种在分布式系统下用来生成全局唯一id的工具 在项目中生成全局唯一ID有很多好处&#xff0c;其中包括&#xff1a; 数据…

k8s集群1.23.0版本部署说明

1.部署 k8s1.23.0版本与1.26.0版本的部署基本差不多&#xff0c;只不过k8s 1.23版本不需要部署cri-docker&#xff0c;所以只需要在1.26.0版本部署的基础上不要cri-docker的部署即可 参考&#xff1a;kubeadm部署k8s 1.26.0版本高可用集群_kubeadm 高可用集群-CSDN博客 搭建…

动手学深度学习1 导学

深度学习导学课 课程基础信息整理00 预告01 课程安排02 深度学习介绍QA 课程基础信息整理 课程安排&#xff1a; https://courses.d2l.ai/zh-v2/ ppt 代码 视频等链接都在文档里有展现 李沐老师课程所用电子书&#xff1a;https://zh-v2.d2l.ai/ B站课程链接&#xff1a; http…

java生产环境问题-mysql写存储过程定时删除大数据量表

问题&#xff1a;生产环境流水表已经达到4000w条数据&#xff0c;不管是查询还是统计都受到了一定程度的影响。所以创建了分表&#xff0c;按照每个月进行存储。但是主表的数据还是很多&#xff0c;所以想到定时删除。 注意&#xff1a;生产环境之前的配置不算高&#xff0c;所…

鸿蒙-arkTs:访问控制授权申请

module.json5文件中 requestPermissions 进行配置&#xff08;值为数组&#xff0c;可配置多个&#xff09; ohos.permission.INTERNET {"name": "ohos.permission.INTERNET" }

算法训练营Day19

#Java #二叉树 #双指针 开源学习资料 Feeling and experiences&#xff1a; 二叉搜索树的最小绝对差&#xff1a;力扣题目链接 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的…

年终数据分析报告这么写,领导超满意

年终总结是每年都要进行的重要工作&#xff0c;不仅是对过去一年的工作进行回顾&#xff0c;也是为了更好地准备和规划未来&#xff0c;值得我们投入更多的时间和精力。而无论是今年的成果还是明年的计划&#xff0c;为了避免假大空&#xff0c;都要基于事实&#xff0c;多用数…

基于SSM框架的个人通讯录系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本个人通讯录就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

【从零开始学习--设计模式--策略模式】

返回首页 前言 感谢各位同学的关注与支持&#xff0c;我会一直更新此专题&#xff0c;竭尽所能整理出更为详细的内容分享给大家&#xff0c;但碍于时间及精力有限&#xff0c;代码分享较少&#xff0c;后续会把所有代码示例整理到github&#xff0c;敬请期待。 此章节介绍策…

配网故障预警与定位装置:减少损失,加速恢复供电

亲爱的朋友们&#xff0c;你们知道吗&#xff1f;现在有一种神奇的装置&#xff0c;可以在配网出现故障时&#xff0c;快速定位并解决问题&#xff0c;减少损失&#xff0c;加速恢复供电&#xff01;这个装置就是恒峰智慧设计的——配网行波型故障预警与定位系统HFP-GZS1000&am…

Docker的安装及使用

目录 安装Docker 安装yum工具 更新本地镜像源 安装docker 启动docker 关闭防火墙 docker启动命令 配置镜像加速 docker的使用 拉取nginx 查看本地镜像 把镜像文件nginx导出成tar文件 查看是否导出成功 ​编辑 删除本地镜像nginx:latest 导入镜像文件nginx 拉取…

共享中药房新突破:亿发打造专业调度与强兼容性的智慧煎药平台

随着共享中药房、智能煎药中心等中医药信息化业务的蓬勃发展&#xff0c;越来越多的医疗机构开始引入自动化设备&#xff0c;将其应用到实际的生产环节中&#xff0c;以辅助或部分替代传统的人工操作。这种自动化设备需要通过智能配方煎药管理系统作为系统平台来进行对接和集成…

Django(一)

1.web框架底层 1.1 网络通信 注意&#xff1a;局域网 个人一般写程序&#xff0c;想要让别人访问&#xff1a;阿里云、腾讯云。 去云平台租服务器&#xff08;含公网IP&#xff09;程序放在云服务器 先以局域网为例 我的电脑【服务端】 import socket# 1.监听本机的IP和…

Swagger2之SpringBoot集成使用

前言&#xff1a; 我们对于Mybatis-Plus的分享较多&#xff0c;都是接触的一些数据库相关的知识&#xff0c;今天给大家带来的是Swagger2 Swagger2 1.介绍&#xff1a; Swagger2是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化Restful风格的web服务&#xff…

(自适应手机版)全屏滚动装修装潢公司网站模板

(自适应手机版)全屏滚动装修装潢公司网站模板 PbootCMS内核开发的网站模板&#xff0c;该模板适用于装修公司网站、装潢公司网站类等企业&#xff0c;当然其他行业也可以做&#xff0c;只需要把文字图片换成其他行业的即可&#xff1b; 自适应手机版&#xff0c;同一个后台&a…

关于MQ,你了解多少?(干货分享之一)

导语 本文梳理笔者 MQ 知识&#xff0c;从消息中间件的基础知识讲起&#xff0c;在有了基础知识后&#xff0c;对市面上各主流的消息中间件进行详细的解析&#xff0c;包括 RabbitMQ、RocketMQ、Kafka、Pulsar&#xff0c;最后再横向对比这几款主流的消息中间件。 消息中间件…

Nodejs 第二十八章(邮件服务)

邮件服务在我们工作中邮件服务充当着一个重要的角色 任务分配与跟踪&#xff1a;邮件服务可以用于分配任务、指派工作和跟踪项目进展。通过邮件&#xff0c;可以发送任务清单、工作说明和进度更新&#xff0c;确保团队成员了解其责任和任务要求&#xff0c;并监控工作的完成情况…