在 finally 块中处理
Dealing with in a finally block
我有一些代码可以创建 JarFile
和 URLClassLoader
,我想在最后关闭它们。自然地,我决定使用 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 7 及更高版本中,尝试使用处理 Closeable
对象的资源。
因此重新格式化您的代码,
try(JarFile jar = ....; URLClassLoader loader = ....;)
{
// work ...
}
只有实现 Closeable
接口的 类 才能以这种方式工作,这两个 类 都满足此条件。
当然有办法封装这个,叫做方法!例如,您可以创建一个 class 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
(例如:封装在 CipherInputStream
中以解密数据,然后写入 FileOutputStream
).然而,我并不是说带有资源的 try-catch 不是一个有用的结构,它在大多数情况下就足够了。
try (JarFile jar = new JarFile(filename);
URLClassLoader loader = URLClassLoader.newInstance(urls)) {
// do stuff
} catch (IOException ex) {
// handle ex
}
我有一些代码可以创建 JarFile
和 URLClassLoader
,我想在最后关闭它们。自然地,我决定使用 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 7 及更高版本中,尝试使用处理 Closeable
对象的资源。
因此重新格式化您的代码,
try(JarFile jar = ....; URLClassLoader loader = ....;)
{
// work ...
}
只有实现 Closeable
接口的 类 才能以这种方式工作,这两个 类 都满足此条件。
当然有办法封装这个,叫做方法!例如,您可以创建一个 class 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
(例如:封装在 CipherInputStream
中以解密数据,然后写入 FileOutputStream
).然而,我并不是说带有资源的 try-catch 不是一个有用的结构,它在大多数情况下就足够了。
try (JarFile jar = new JarFile(filename);
URLClassLoader loader = URLClassLoader.newInstance(urls)) {
// do stuff
} catch (IOException ex) {
// handle ex
}