Java周二生效! 优先尝试资源

今天,我们有一个主题与我们上周讨论的主题完全一致。 上周,主题是定型剂和清洁剂。 这些的常见用途之一是清理资源。 在此博客文章中,我们将进一步详细介绍上一篇文章末尾所暗示的更好方法。

由于种种原因,有许多资源在使用后需要手动关闭。 这通常是通过使用关 method on the object. We of course don't want to leak resources or leave items in a half handled state. This being the case we may consider putting the 关 method in a 最后块。 例如:

static List<Object> getDbValues() {
  EntityManager em = getEntityManager();
  try {
    return em.createNativeQuery("SELECT * FROM myTable").getResultsList();
  } finally {
    em.close();
  }
}

这样就可以了,看起来还不错。 随着我们添加更多资源,它的确变得更加混乱和容易出错。

static List<Object> getDbValues() {
  OutputStream output = getOutputStream();
  InputStream input = getInputstream();
  try {
    try {
      // do work
    } finally {
      input.close();
    }
  } finally {
    output.close();
  }
}

这开始变得越来越粗糙,难以遵循。 我什至做对了吗? 我不相信。 很容易搞砸。 作者甚至承认,多年来他的一本书中都把这种模式弄乱了,没有人意识到。 即使使用正确的代码,错误处理的细微之处也无法得到很好的处理。 异常可能会相互覆盖,我们可能会在发生的堆栈跟踪中丢失有价值的信息。 您可以编写代码来处理此问题,但是它既复杂又丑陋,因此没人能这样写。

因此,在Java 7中,我们得到了更好的答案,尝试资源。 有了这个构造,任何实现的类自动关闭可以用Java处理它的关闭。 因此上面的例子看起来像:

try(InputStream input = new FileInputStream("file");
    OutputStream output = new FileOutputStream("other")) {
            // do work
}

这要简单得多。 它处理的内容比上一个示例还要多。 这实际上不是代码保留的方式。 上面的代码被编译器转换为更加冗长的结果。 让我们来看看:

InputStream input = new FileInputStream("file");
Throwable var2 = null;

try {
    OutputStream output = new FileOutputStream("other");
    Throwable var4 = null;

    try {
        //do work
    } catch (Throwable var27) {
        var4 = var27;
        throw var27;
    } finally {
        if (output != null) {
            if (var4 != null) {
                try {
                    output.close();
                } catch (Throwable var26) {
                    var4.addSuppressed(var26);
                }
            } else {
                output.close();
            }
        }

    }
} catch (Throwable var29) {
    var2 = var29;
    throw var29;
} finally {
    if (input != null) {
        if (var2 != null) {
            try {
                input.close();
            } catch (Throwable var25) {
                var2.addSuppressed(var25);
            }
        } else {
            input.close();
        }
    }

}

哇! 那变得非常激烈。 但是,如果您仔细分析它,您会发现它正在做我们希望的工作,同时可以更彻底地处理异常。

Final thought. In a previous post I mentioned the tool Lombok. I very much think this is a good tool. Inside the bag of tricks of Lombok there is an annotation @Cleanup. It looks like it will do something very similar to the above. So what makes these two different. While it is correct that they do similar things they do have a slight different. The main difference is that @Cleanup simply writes the try-finally combinations like we did above but doesn't do any magic handling the exception handling. So while @Cleanup does give us the safety of a finally block we do lose the specialized exception handling.

所以你有它。 使用try-with-resources。 更简单,更清洁,更安全,这确实是一个我看不到太多缺点的地方。

from: https://dev.to//kylec32/effective-java-tuesday-prefer-try-with-resources-2om9

发布了0 篇原创文章 · 获赞 0 · 访问量 644

猜你喜欢

转载自blog.csdn.net/cunxiedian8614/article/details/105691150
今日推荐