如何关闭Java流



每当我看到Java 6流处理时,它都是这样做的:

public void myMethod() throws Exception
{
    InputStream stream = null;
    try
    {
        stream = connection.openConnection();
        ...
    }
    finally
    {
        if( stream != null )
        {
            stream.close();
        }
    }
}

但我不明白为什么这是必要的。这不是同样的方法吗?

public void myMethod() throws Exception
{
    InputStream stream = connection.openConnection();
    try
    {
        ...
    }
    finally
    {
        stream.close();
    }
}

如果openConnection()失败,那么stream将不会被分配,并且无论如何都没有什么可关闭的,不是吗?

我同意你的看法。

null赋值的额外步骤是不必要的,而且很难看。你甚至可以让stream成为决赛。

我唯一会写这样的东西的时候是,如果您有多个资源需要清理(JDBC经常发生这种情况),并且您希望避免多个嵌套的try/finaly块(但通常我都会选择这些块)。

使用Java7,您可以使用try-with-构造。

每次使用类似的构造检索InputStream时

InputStream stream = connection.openConnection();

有三种可能的结果:要么该方法返回正确的InputStream,要么返回null,要么抛出异常。

让我们看看所有三种可能性:

1) 该方法返回了正确的输入流。

在这种情况下,try块只是继续,如果它没有遇到任何其他问题(也称为异常),它通常在执行finally块后结束。

2) 该方法返回null。

在这种情况下,您还应该在try块中进行null检查。如果是这样的话,try块通常什么都不做,finally块也必须进行null检查。否则,你的最后一个盖帽会抛出一个NPE。

如果不防止返回null,try块中的代码将抛出NPE(我假设流变量在那里使用)。在这种情况下,finally块将被执行,并将再次抛出一个NPE,如果它没有进行null检查的话。在后一种情况下,实际上只有来自finally块的第二个NPE被抛出给调用者。

3) 用于检索输入流的方法调用引发异常。

在这种情况下,try块将结束,这将立即导致finally块执行,然后方法将突然结束。但有哪个例外?这取决于情况。

考虑抛出的异常是IOException,在大多数情况下都会抛出它。首先,变量仍将具有null引用!如果finally块没有空检查,那么它将再次抛出一个NPE。在这种情况下,第一个异常(IOE)将被忘记,因为只有NPE会被传递给方法的调用。这不是个好主意。

总而言之,空检查确实是必要的。

现在,Java 7推出了它的try with resources构造。这确实是一个更好的机制,因为它有一个隐式的finally块,在那里流是关闭的。如果try块中存在异常,并且隐式finally块也抛出异常,则tnow第一个异常(来自try块内部)将传递给调用者。这更合适。而且语法读起来更好。

相关内容

  • 没有找到相关文章

最新更新