【问题标题】:Dealing with in a finally block [duplicate]在finally块中处理[重复]
【发布时间】:2015-06-06 15:54:34
【问题描述】:

我有一些代码可以创建JarFileURLClassLoader,我想在最后关闭这两个代码。自然地,我决定使用finally 块来处理清理工作:

JarFile jar = ...;
URLClassLoader loader = ...;
try {
    // work ...
} finally {
    jar.close();
    loader.close();
}

但是,两个close() 调用都可能引发异常,因此如果jar.close() 会引发异常,则将无法到达loader.close()。我想解决这个问题的一种方法是用 try-catch 块包围jar.close()

JarFile jar = ...;
URLClassLoader loader = ...;
try {
    // work ...
} finally {
    try {
        jar.close();
    } catch(IOException e) {
    } 
    loader.close();
}

但这看起来既丑陋又过分。有没有一种优雅的方式来处理finally 块中与清理相关的异常?

【问题讨论】:

  • 不应该倒序关闭项目吗?

标签: java exception-handling try-finally


【解决方案1】:

在 Java 7 及更高版本中,可以尝试处理 Closeable 对象的资源。

因此重新格式化您的代码,

try(JarFile jar = ....; URLClassLoader loader = ....;) 
{
    // work ...
}

只有实现Closeable 接口的类才能以这种方式工作,这两个类都符合这个标准。

【讨论】:

  • 不错不错,我倾向于怀念那些“新”功能。好像我会在一个活动项目中重构一些代码:)
  • 是的,我真的很喜欢这个功能,我一直使用closeQuietly(Closeable... closeable)的方法来完成与Dici的回答相同的事情,但之前允许一次调用。
【解决方案2】:

使用try-with-resources:

    try (JarFile jar = new JarFile(filename);
            URLClassLoader loader = URLClassLoader.newInstance(urls)) {
        // do stuff
    } catch (IOException ex) {
        // handle ex           
    }

【讨论】:

    【解决方案3】:

    当然有办法封装这个,叫做方法!例如,您可以创建一个类IOUtils,如下所示:

    public class IOUtils {
        // this class is not meant to be instantiated
        private IOUtils() { }
    
        public static void closeQuietly(Closeable c) {      
           if (c == null) return;
           try {
              c.close();
           } catch (IOException e) { }
        }
    }
    

    然后,

    JarFile jar = ...;
    URLClassLoader loader = ...;
    try {
        // work ...
    } finally {
        closeQuietly(jar);
        loader.close();
    }
    

    正如 Patrick J Abae II 所说,您也可以对资源使用 try-catch,但您不能总是这样做,例如,如果您首先在try-catch,然后通过封装第一个创建几种不同类型的InputStream(例如:封装在CipherInputStream 中以破译数据然后写入FileOutputStream)。然而,我并不是说 try-catch with resources 不是一个有用的结构,它在大多数情况下就足够了。

    【讨论】:

    • 你认为应该如何使用这个类?
    • @LutzHorn 你是什么意思?它旨在通过静态方法用作任何实用类
    • 好吧,现在您已经编辑了答案,它变得更清晰了。
    猜你喜欢
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2019-03-31
    • 2011-08-26
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多