3

我有一些创建 aJarFile和 a 的代码URLClassLoader,我想在最后关闭它们。自然地,我决定使用finally块来处理清理:

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

但是,两个close()调用都可能引发异常,因此如果jar.close()会引发异常,则loader.close()不会到达。我考虑解决此问题的一种方法是jar.close()使用 try-catch 块:

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

但这似乎丑陋和过分。是否有一种优雅的方式来处理finally块中与清理相关的异常?

4

3 回答 3

6

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

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

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

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

于 2015-06-06T15:58:12.453 回答
2

当然有一种方法可以封装这个,叫做方法!例如,您可以创建一个类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,但不能总是这样做,例如,如果您首先InputStream在 try-catch 中创建一个,然后InputStream通过封装创建几种不同类型的第一个(例如:封装在 aCipherInputStream中以破译数据,然后写入 a FileOutputStream)。然而,我并不是说使用资源的 try-catch 不是一个有用的结构,在大多数情况下它就足够了。

于 2015-06-06T15:59:04.500 回答
2

使用try-with-resources

    try (JarFile jar = new JarFile(filename);
            URLClassLoader loader = URLClassLoader.newInstance(urls)) {
        // do stuff
    } catch (IOException ex) {
        // handle ex           
    }
于 2015-06-06T16:00:54.923 回答