繁体   English   中英

这是释放Java资源的安全方法吗?

[英]Is this a safe way to release resources in Java?

通常,当代码需要一些需要释放的资源时,我会这样看待它:

InputStream in = null;
try{
    in = new FileInputStream("myfile.txt");
    doSomethingWithStream(in);
}finally{
    if(in != null){
        in.close();
    }
}

我不喜欢的是,您必须将变量初始化为null,然后将其设置为另一个值,并在finally块中通过检查资源是否为null来检查资源是否已初始化。 如果不为null,则需要释放它。 我知道我很挑剔,但是我觉得可以做得更干净。

我想做的是这样的:

InputStream in = new FileInputStream("myfile.txt");
try{
    doSomethingWithStream(in);
}finally{
    in.close();
}

在我看来,这看起来几乎和上一个一样安全。 如果资源初始化失败并引发异常,则无需执行任何操作(因为我没有获得资源),因此它不必位于try块内。 我唯一担心的是,是否有某种方式(我没有Java认证)可以在操作之间引发异常或错误?

更简单的示例:

Inputstream in = new FileInputStream("myfile.txt");
in.close();

有没有什么办法可以让流最终被打开,而最终尝试阻止该流?

编辑:

也许我应该省略最后一个示例,因为它会使所有人感到困惑。 这不应该是初学者级别的问题。 我知道最后尝试执行的操作,并且我知道在上一个示例的中间是否存在doSomethingWithStream是不安全的。 这就是为什么它不存在的原因。 我接受了Eyals的回答,因为这正是我想要的。 有一种方法可以在两个操作之间引起异常,这会使中间示例不安全(使用Thread.stop),但是由于它是使用不赞成使用的调用而创建的,因此无论您做什么都可能使您混乱,因此我觉得使用中间的例子。

中间的样本是安全的-最后一个样本不是。

try-finally块意味着即使doSomethingWithStream引发异常,流也将关闭。 是的,您可以捕获所有异常,然后以这种方式关闭流-但是让异常冒泡到调用者处,而是通过finally块关闭流,这要简单得多。

实际上,在上一个代码示例中的两次调用之间可能会发生异常,并使资源保持打开状态。 如果在流构建之后立即使用Thread.stop()或Thread.stop(Throwable)将另一个线程强行停止该线程,则该线程将引发异常(在第一种情况下为ThreadDeath),并且不会处理资源。的。

但这正是不推荐使用这些方法的原因...

调查龙目岛项目 它具有@Cleanup批注,该批注可在局部变量上设置,它将在编译时自动生成代码以清理资源。

 import lombok.Cleanup;
 import java.io.*;

 public class CleanupExample {
   public static void main(String[] args) throws IOException {
     @Cleanup InputStream in = new FileInputStream(args[0]);
     @Cleanup OutputStream out = new FileOutputStream(args[1]);
     byte[] b = new byte[10000];
     while (true) {
       int r = in.read(b);
       if (r == -1) break;
       out.write(b, 0, r);
     }
   }
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM