
“嗨,阿米戈!”
“我只是决定和你讨论一下finalize ()方法。”
“如果你还记得的话,finalize() 是一种特殊的方法,在垃圾收集器销毁对象之前由对象调用。”
“此方法的主要目的是通过关闭文件、I/O 流等来释放已使用的外部非 Java 资源。”
“不幸的是,这个方法没有达到我们的预期。Java 虚拟机可以推迟销毁对象,也可以推迟调用 finalize 方法,只要它愿意。而且,它不保证这个方法会被执行根本没有被调用。有很多情况下它没有被调用,都是以 «优化» 的名义。
“我有两个推荐信给你:”
Joshua Bloch 写了一篇关于此方法的好文章:链接 我将转述一小段摘录:
|
如果我在采访中说 finalize 是一个有害且危险的拐杖,其存在本身就令人困惑,我是对的吗? |
“好吧,这让我很高兴,艾莉。”
“Java 7 有一个新语句来替换finalize方法。它被称为try-with-resources。它并不是finalize的真正替代品,而是一种替代方法。”
“它是不是像 try-catch,但有资源?”
“这几乎就像try-catch。事情是,与finalize () 方法不同,try- catch-finally语句中的finally块总是被执行。程序员在需要释放资源时也使用了这种技术,关闭线程等。
“这是一个例子:”
InputStream is = null;
try
{
is = new FileInputStream("c:/file.txt");
is.read(…);
}
finally
{
if (is != null)
is.close();
}
“无论try块是否正常执行或出现异常,finally块都会被调用,并且有可能在那里释放占用的资源。”
“因此,在 Java 7 中,决定将这种方法正式化,如下所示:”
try(InputStream is = new FileInputStream("c:/file.txt"))
{
is.read(…);
}
“这个特殊的try语句称为try-with-resources(类似于集合如何为称为foreach的替代方法)。”
“注意在try之后有括号声明变量和创建对象。这些对象可以在花括号指示的try块内使用。当try块执行完成时,无论它是正常结束还是在那里是一个例外,将在括号内创建的任何对象上调用 close() 方法。”
“真有趣!这个符号比之前的符号要紧凑得多。我不确定我是否理解它。”
“没你想的那么难。”
“那么,我可以在括号中指定每个对象的类别吗?”
“是的,当然,否则括号就没有什么用了。”
“如果我需要在退出 try 块后调用另一个方法,我应该把它放在哪里?”
“这里的事情有点微妙。Java 7 引入了以下接口:”
public interface AutoCloseable
{
void close() throws Exception;
}
“你的类可以实现这个接口。然后你可以在 try-with-resources 语句中使用它的对象。只有这样的对象才能在 try-with-resources 语句的括号内创建,以实现 «automatic closure»。
“换句话说,我需要重写 close 方法并在其中编写代码来 «clean up» 我的对象,我不能指定另一个方法吗?”
“是的。但您可以指定多个对象——只需用分号分隔它们:”
try(
InputStream is = new FileInputStream("c:/file.txt");
OutputStream os = new FileOutputStream("c:/output.txt")
)
{
is.read(…);
os.write(…);
}
“那好多了,但没有我希望的那么酷。”
“没那么糟糕。你会习惯的。随着时间的推移。”
GO TO FULL VERSION