[英]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.