处理一个finally块

时间:2015-06-06 15:54:35

标签: java exception-handling try-finally

我有一些代码可以创建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块中与清理相关的异常?

3 个答案:

答案 0 :(得分:6)

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

重新格式化您的代码,

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

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

答案 1 :(得分: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和资源,但是你不能总是这样做,例如,如果你第一次创建{{1在try-catch中,然后通过封装第一个来创建几种不同类型的InputStream(例如:封装在InputStream中以解密数据,然后写入CipherInputStream )。然而,我并不是说资源的尝试捕获不是一个有用的结构,在大多数情况下它就足够了。

答案 2 :(得分:2)

使用try-with-resources

#include <stdio.h>
int main(int argc, char *argv[])
{
    if (argc != 4)
    {
        printf("Error: you must use 4 arguments\n\n");
        return 1;
    }

    int x = argv[1][0] - '0';
    int y = argv[3][0] - '0';
    int z = 0;

    if (strcmp(argv[2], "+") == 0)
        z = x + y;
    else if (strcmp(argv[2], "-") == 0)
        z = x - y;
    else if (strcmp(argv[2], "*") == 0)
        z = x * y;
    else
        z = x / y;
    printf("Result = %d\n\n", z);
    return 0;
}