概括
我有一个可关闭的类型,CloseableClass
它可以在其构造函数、方法甚至可能在内部抛出 IOError close
。我想使用 try-with-resources 并且仍然以与使用期间的错误不同的方式处理构建期间的错误(使用包括清理)。更好的是,我想编写可维护的代码。
假设您希望构造一个可关闭的类实例并将其与 try-with-resources 语句一起使用。它可以抛出IOException
它的构造函数和 try-with-resources 主体中使用的方法:
import java.io.Closeable;
import java.io.IOException;
import java.util.Random;
public class CloseableClass implements Closeable {
public CloseableClass() throws IOException {
if (new Random().nextBoolean()) {
throw new IOException();
}
}
public void internetStuff() throws IOException {
if (new Random().nextBoolean()) {
throw new IOException();
}
}
public void close() throws IOException {
if (new Random().nextBoolean()) {
throw new IOException();
}
}
public static void main(String[] args) {
try (CloseableClass closeable = new CloseableClass()) {
closeable.internetStuff();
}
catch (IOException e) {
System.out.println("Bad error!");
}
}
}
假设您要分别处理构造函数和正文中抛出的错误。有支持的方法吗?在 Python 中,我会这样做:
try:
closeable = CloseableClass()
except IOException:
print("Constructor error")
return
try:
with closeable:
closeable.internet_stuff()
except IOException:
print("Body error")
但在 Java 中,你不能不为对象分配第二个名称:
CloseableClass closeable_;
try {
closeable_ = new CloseableClass();
}
catch (IOException e) {
System.out.println("Constructor error!");
return;
}
try (CloseableClass closeable = closeable_) {
closeable.internetStuff();
}
catch (IOException e) {
System.out.println("Body error!");
}
有人告诉我,这是“不可维护的代码”,主要是因为使用了closeable_
,我离同意也不远了。我希望避免使用 try-finally ,因为那样你会遇到更糟糕的模拟它的问题:
CloseableClass closeable;
try {
closeable = new CloseableClass();
}
catch (IOException e) {
System.out.println("Constructor error!");
return;
}
try {
closeable.internetStuff();
}
catch (IOException e) {
try {
closeable.close();
}
catch (IOException ignore) {
// Already dealing with this
}
System.out.println("Body error!");
}
finally {
try {
closeable.close();
}
catch (IOException e) {
System.out.println("Body error!");
}
}
请注意,这需要第二次调用才能close
成为无操作,测试类不遵守(请注意,AutoCloseable
不需要这样做,尽管Closeable
确实如此)。close
当不能扔时,这有点好,但不多。
基本上问题是
close
可以扔- 处理前关闭
IOException
以防止打印"Body error!"
两次 - 如何使它与来自 try-with-resources 的多个初始化程序一起工作并不明显
- 无论如何,您最终都会复制代码。
我只是被迫忍受“不可维护的代码”还是我忽略了处理这个问题的好方法?