gpt4 book ai didi

java - 在与主体分开的 try-with-resources 中捕获对象构造期间的错误

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:22:41 25 4
gpt4 key购买 nike

总结

我有一个可关闭的类型,CloseableClass,它可以在其构造函数、方法中甚至在 close 中抛出 IOError。我想使用 try-with-resources 并且仍然以不同于使用期间的错误处理构建期间的错误(使用包括清理)。更好的是,我想编写可维护的代码。


假设您希望构造一个可关闭的类实例并将其与 try-with-resources 语句一起使用。它可以在其构造函数和 try-with-resources 主体中使用的方法中抛出 IOException:

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 不能抛出时,这会好一点,但不会太多。

基本上问题在于

  • 关闭可以抛出
  • 在处理 IOException 之前关闭以防止打印 “Body error!” 两次
  • 如何让它与 try-with-resources 中的多个初始化程序一起工作并不明显
  • 无论如何,您最终都会重复代码。

我是被迫忍受“无法维护的代码”,还是忽略了处理这个问题的好方法?

最佳答案

“请注意,这需要第二次调用才能关闭” - 不,您不需要 close()catch block ,如 finally block 将始终被执行。您将只使用 close()里面catch如果您使用类似 System.exit() 的调用终止 JVM,则阻塞在catch堵塞。通常你会抛出 Exception来自 catch 的来电者时钟,但您将在 finally 中执行清理工作阻塞大部分时间。

Try-with-resource 更好,但您可以使用 Exception 的类型和描述抛出破译什么地方出了问题。

编辑

据我所知,我建议:

1) 尝试资源:

try(Resource resource = new Resource()){
// use resource.
}catch(Exception e){
// handle exception.
// OR better to throw exception to caller.
throw e;
}

2) 常规样式:

Resource resource = null;
try{
resource = new Resource();
// use resource
}catch(Exception e){
// handle exception.
// OR better to throw exception to caller.
throw e;
} finally {
if(resource != null){
try{
resource.close();
} catch(Exception e){
// most of time you wont or cant do anything here.
}
}
}

关于java - 在与主体分开的 try-with-resources 中捕获对象构造期间的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26943481/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com