通常当代码需要一些需要释放的资源时,我看到它是这样做的:
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();
有没有什么方法可以让一个try-finally块阻止的流被打开?
修改
也许我应该省略最后一个例子,因为它让每个人都感到困惑。这不应该是一个初学者级别的问题。我知道try-finally做了什么,我知道如果在最后一个例子中间有doSomethingWithStream则不安全。这就是它不存在的原因。我接受了Eyals的回答,因为这正是我所寻找的。有一种方法可以在两个操作之间导致异常,这会使中间示例不安全(使用Thread.stop),但由于它是使用不推荐的调用制作的,并且无论你做什么都会弄乱你,所以我觉得安全使用中间的例子。
答案 0 :(得分:2)
中间样本是安全的 - 最后一个样本不是。
try-finally块意味着即使doSomethingWithStream
抛出异常,流也会关闭。是的,您可以捕获所有异常,然后以这种方式关闭流 - 但是让异常冒泡到调用者更简单,但是通过finally块关闭流。
答案 1 :(得分:1)
实际上,最后一个代码示例中的2个调用之间可能会发生异常,并使资源保持打开状态。如果线程在流构造之后立即使用Thread.stop()或Thread.stop(Throwable)被另一个线程猛烈地停止,则线程将抛出异常(第一种情况下为ThreadDeath),并且资源不会被处置的。
但这正是这些方法被弃用的原因......
答案 2 :(得分:0)
查看Project Lombok。它有一个@Cleanup注释,可以在局部变量上设置,auto-generate code at compilation time将清理资源。
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);
}
}
}