我有一个可关闭类型,CloseableClass,它可以在其构造函数、方法甚至内部抛出IOError。我想使用try-with-resources,但在处理构建过程中的错误时仍然与使用过程中的错误不同(使用包括清理)。更好的是,我想编写可维护的代码。
假设您希望构造一个可关闭的类实例并将其与try-with资源语句一起使用。它可以在其构造函数和try-with资源主体中使用的方法中抛出
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\uu”,我对此表示同意。我希望避免使用try finally,因为如果使用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!");
}
}
注意,这需要第二次调用关闭(no op),测试类不遵守这一点(注意,自动关闭(AutoCloseable)不需要这一点,尽管关闭(AutoCloseable)需要这一点)。如果关闭时不能抛出,但不会抛出太多,这会更好一些。
基本上问题是
关闭
可以抛出
- 在处理
IOException
之前关闭以防止打印“身体错误!”
两次 - 如何让它与来自try with资源的多个初始化程序一起工作并不明显
- 无论如何,您最终都会复制代码。
我是被迫生活在“无法维护的代码”中,还是忽略了一个处理这个问题的好方法?
从Java9开始,try-with-资源已经接受了“有效的最终”变量,因此您不需要重新分配变量。
CloseableClass closeable;
try {
closeable = new CloseableClass();
}
catch (IOException e) {
System.out.println("Constructor error!");
return;
}
try (closeable) {
closeable.internetStuff();
}
catch (IOException e) {
System.out.println("Body error!");
}
一种解决方案是定义一种方法,将初始化错误封装在自定义异常类型中,然后使用该方法确定错误发生的时间。
private CloseableClass createCloseable() throws CloseableCreateException{
try {
return new CloseableClass();
} except (IOException e) {
throw new CloseableCreateException(e);
}
}
try (CloseableClass closeable = initCloseable()) {
closeable.internetStuff();
} catch (CloseableCreateException e) {
System.out.println("Constructor error!");
} catch (IOException e) {
System.out.println("Body error!");
}
另一个简单但有点不优雅的解决方案是使用布尔标志:
boolean init = true;
try (CloseableClass closeable = new CloseableClass()) {
init = false;
closeable.internetStuff();
} catch (IOException e) {
if (init) {
System.out.println("Constructor error!");
} else {
System.out.println("Body error!");
}
}
'注意,这需要第二次调用close以成为no op'-不,您不需要在catch
块中执行close()
,因为最后总是要执行。如果使用类似于系统的调用终止JVM,则只会在catch中使用close()
block。exit()在捕捉块中。通常,您会从catch
时钟向调用方抛出异常,但您将在大部分时间内最终执行清理。
尝试与资源更好,但您可以使用抛出的
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程序示例中: 当在静态方法example()的正文中抛出OutOfMemoryError错误时,在终止静态方法example()之前,连接“con”和语句“stmt”是否会自动关闭,尽管没有任何“cat”捕获这些错误,因此在main()的其余代码中,是否确定这两个对象已关闭? 谢谢
考虑来自Java文档的以下代码。 根据Java文档, 在示例readFirstLineFromFile中,如果从try块和try with resources语句抛出异常,则方法readFirstLineFromFile抛出从try块抛出的异常;禁止从try with resources块引发的异常。 另一方面,也提到了 由于BufferedReader实例是在try with resource语
我有一个文件位于/res/introducted。xml。我知道我可以通过两种方式访问它: 1) R.引入的资源 2)一些绝对/相对URI 我正在尝试创建一个File对象以将其传递给特定的类。我该怎么做?
我编写代码并使用CompatResources获取字体并设置为TypeFace以查看错误Fabric.io报告了一些崩溃。 由android引起。所容纳之物无法检索res.Resources$NotFoundException字体资源ID#0x7f090000。 这是我的代码: 谢谢你的帮助。
我有下面的方法,它使用Apache Commons Http客户机向给定的URI发送异步GET,并返回Future和响应。 CloseableHttpAsyncClient实现了Closeable,因此我使用try/resource结构。 下面您可以看到其用法: 问题是,当我调用get on a future时,它不会返回所需的HttpResponse。如果我使用重载的get()方法,它将一直等待
id String - 调用[navigator.webkitGetUserMedia]时可用作 chromeMediaSourceId约束的窗口或屏幕的标识符。 标识符的格式为 window:XX或 screen:XX,其中 XX是一个随机生成的数字。 name String - 屏幕源将被命名为 Entire Screen 或 Screen <index>,而窗口源的名称将匹配窗口标题。 th