Effective Java笔记(9)try-with-resources 优先于 try -finally

这篇具有很好参考价值的文章主要介绍了Effective Java笔记(9)try-with-resources 优先于 try -finally。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        Java 类库中包括许多必须通过调用 close 方法来手工关闭的资源 。 例如 InputStream 、OutputStream 和 java.sql.Connection 。 客户端经常会忽略资源 的关闭 ,造成严重的性能后果也就可想而知了 。 虽然这其中的许多资源都是用终结方法作为安全网,但是效果并不理想。

        根据经验,try -finally 语句是确保资源会被适时关闭的最佳方法,就算发生异常或者返回也一样 :

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

        这看起来好像也不算太坏,但是如果再添加第二个资源,就会一团糟了 :

static void copy(String src, String dst) throws IOException {
    InputStream in = new FileInputStream(src) ;
    try {
        OutputStream out = new FileOutputStream(dst) ;
        try {
            byte[] buf = new byte[BUFFER_ SIZE];
            int n;
            while ((n = in.read(buf)) >= 0)
                out.write(buf,0,n);
        } finally {
            out.close();
        }
    } finally {
        in.close() ;
    }
}

        这可能令人有点难以置信,不过就算优秀的程序员也会经常犯这样的错误 。

        即使用 try-finally 语句正确地关闭了资源,如前两段代码范例所示,它也存在着些许不足 。 因为在 try 块和 finally 块中的代码,都会抛出异常 。 例如在 firstLineOfFile方法中,如果底层的物理设备异常,那么调用 readLine 就会抛出异常,基于同样的原因,调用 close 也会出现异常 。 在这种情况下,第二个异常完全抹除了第一个异常 。 在异常堆枝轨迹中,完全没有关于第一个异常的记录,这在现实的系统中会导致调试变得非常复杂,因为通常需要看到第一个异常才能诊断出问题何在 。 虽然可以通过编写代码来禁止第二个异常,保留第一个异常,但事实上没有人会这么做,因为实现起来太烦琐了 。

        当 Java 7 引人 try -with-rsources 语句时,所有这些问题一下子就全部解决了 。 要使用这个构造的资源,必须先实现 AutoCloseable 接口,其中包含了单个返回 void 的 close 方法 。Java 类库与第三方类库中的许多类和接口,现在都实现或扩展了AutoCloseable 接口 。 如果编写了 一个类,它代表的是必须被关闭的资源,那么这个类也应该实现 AutoCloseable 。

        以下就是使用 try-with-resources 的第一个范例:

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

        以下是使用 try -with -resources 的第二个范例:

static void copy(String src, String dst) throws IOException {
    try (InputStream in = new FileInputStream(src);
    OutputStream out = new FileOutputStream(dst)) {
        byte[] buf = new byte[BUFFER_ SIZE];
        int n;
        while ((n = in.read(buf)) >= 0)
        out.write(buf,0,n);
    }
}

        使用 try-with-resources 不仅使代码 变得更简洁易懂,也更容易进行诊断 。以 firstLineOfFile 方法为例,如果调用 readLine 和(不可见的) close 方法都抛出异常,后一个异常就会被禁止,以保留第一个异常 。 事实上,为了保留你想要看到的那个异常,即便多个异常都可以被禁止 。 这些被禁止的异常并不是简单地被抛弃了,而是会被打印在堆枝轨迹中,并注明它们是被禁止的异常 。 通过编程调用 getSuppressed 方法还可以访问到它们,getsuppres sed 方法也已经添加在 Java 7 的 Throwable 中了 。

        在try-with-resources语句中还可以使用catch子句,就像在平时的try-finally语句中一样。这样既可以处理异常,又不需要再套用一层代码。下面举一个稍费了点心思的范例,这个firstLineOfFile方法没有抛出异常,但是如果它无法打开文件,或者无法从中读取,就会返回一个默认值:

static String firstLineOfFile(String path, String defaultVal) {
    try (BufferedReader br = new BufferedReader(
        new FileReader(path))) {
        return br.readLine();
    } catch (IOException e) {
        return defaultVal;
    }
}

        结论很明显:在处理必须关闭的资源时,始终要优先考虑用 try-with-resources ,而不是用 try-finally 。 这样得到的代码将更加简洁、清晰,产生的异常也更有价值 。 有了 try­-with-resources 语句,在使用必须关闭的资源时,就能更轻松地正确编写代码了 。 实践证明,这个用 try-finally 是不可能做到的 。文章来源地址https://www.toymoban.com/news/detail-554050.html

到了这里,关于Effective Java笔记(9)try-with-resources 优先于 try -finally的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Effective Java笔记(5)优先考虑依赖注入来引用资源

            有许多类会依赖一个或多个底层的资源 。 例如,拼写检查器需要依赖词典 。 因此,像下面这样把类实现为静态工具类的做法并不少见(详见第 4 条):         同样地,将这些类实现为 Singleton 的做法也并不少见(详见第 3 条) :         以上两种方法

    2024年02月15日
    浏览(48)
  • Effective Java笔记(6)避免创建不必要的对象

            一般来说,最好能重用单个对象,而不是在每次需要 的时候就创建一个相同功能的新对象 。 重用方式既快速,又流行 。 如果对象是不可变的( immutable ) (详见第 17 条),它就始终可以被重用 。         作为一个极端的反面例子,看看下面的语句 :    

    2024年02月15日
    浏览(39)
  • Effective Java笔记(11)覆盖 equals 时总要覆盖 hashCode

             在每个 覆盖了 equals 方法的类中,都 必须 覆盖 hashCode 方法 。 如果不这样做的话,就会违反 hashCode 的通用约定,从而导致该类无法结合所有基于散列的集合一起正常运作,这类集合包括 HashMap 和 HashSet 。 下面是约定的内容,摘自 Object 规范: 1、在应用程序的执

    2024年02月15日
    浏览(57)
  • Effective Java笔记(3)用私有构造器或者枚举类型强化 Singleton 属性

            Singleton 是指仅仅被实例化一次的类 。Singleton 通常被用来代表一个无状态的对象,如函数,或者那些本质上唯一的系统组件 。 使类成为 Singleton会使它的害户端测试变得十分困难 ,因为不可能给 Singleton 替换模拟实现,除非实现一个充当其类型的接口 。      

    2024年02月15日
    浏览(51)
  • Effective Java笔记(16)要在公有类而非公有域中使用访问方法

            有时候,可能需要编写一些退化类,它们没有什么作用,只是用来集中实例域 :         由于这种类的数据域是可以被直接访问的,这些类没有提供 封装 ( encapsulation )的功能。 如果不改变 API,就无法改变它的数据表示法, 也无法强加任何约束条件;当域

    2024年02月16日
    浏览(42)
  • 安装或者卸载软件时遇到trying to use is on a network resource that is unavailable

    The feature you are trying to use is on a network resource is unavailable 点击ok之后会有Click OK to try again, or enter an alternate path to afolder containing the installation package \\\'EndNote x9v19.0.0.12062 Setup(1).msi\\\' in the box below. 具体如下图所示: 博主花费一早上的时间终于解决这个问题,主要是由于 您试图使用的

    2024年02月07日
    浏览(225)
  • Python 异常处理 try-except,else,finally, with 语句的区别

    在日常编写程序时,难免会遇到错误,有的是由于疏忽造成的语法错误,有的是程序内部隐含逻辑问题造成的数据错误,还有的是程序运行时与系统的规则冲突造成的系统错误,等等。 总的来说,编写程序时遇到的错误可大致分为 2 类,分别为语法错误和运行时错误。 Pyth

    2023年04月08日
    浏览(38)
  • 【前后端对接迷惑问题】无法加载响应数据:No resource with given identifier found

    开发对接过程中遇到的问题,希望对你有帮助!

    2024年02月11日
    浏览(50)
  • effective c++ 笔记

    TODO:还没看太懂的篇章 item25 item35 模板相关内容 可以将C++视为以下4种次语言的结合体: C 面向对象 模板 STL 每个次语言都有自己的规范,因此当从其中一个切换到另一个时,一些习惯或守则是可能会发生变化的。 用const替换#define有以下2个原因: #define定义的符号名称可能没

    2024年02月10日
    浏览(28)
  • C++笔记-effective stl

    熟悉stl本身 慎重选择stl容器,每一种stl容器对应不同的使用场景,比如deque往往比vector更加合适 封装stl容器,积极的使用stl,可以高效的使用它 积极使用其对应迭代器使用的函数,比如做相加运算使用accumulate替代for循环,可以更加高效 调用对应的函数的时候,不使用过于复

    2024年01月18日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包