mal*_*rdz 16 java exception-handling try-catch-finally
我正在学习在线java课程,使用Java编程简介.
在I/O章节中,下面的代码引入了以下语句:
顺便说一句,在本程序结束时,您将在try语句中找到我们的第一个有用的finally子句示例.当计算机执行try语句时,无论如何都保证finally子句中的命令被执行.
该程序位于第11.2.1节的末尾,是一个简单的程序,只读取文件中的一些数字并以相反的顺序写入.
main方法中的相关代码是(data是Reader,result是Writer):
try {
// Read numbers from the input file, adding them to the ArrayList.
while ( data.eof() == false ) { // Read until end-of-file.
double inputNumber = data.getlnDouble();
numbers.add( inputNumber );
}
// Output the numbers in reverse order.
for (int i = numbers.size()-1; i >= 0; i--)
result.println(numbers.get(i));
System.out.println("Done!");
} catch (IOException e) {
// Some problem reading the data from the input file.
System.out.println("Input Error: " + e.getMessage());
} finally {
// Finish by closing the files, whatever else may have happened.
data.close();
result.close();
}
Run Code Online (Sandbox Code Playgroud)
所以我想知道为什么finally子句在这种情况下有用,因为try或catch子句中没有其他退出点.相反的方法难道不能只在主体中吗?
我想也许是因为理论上可能会有一些其他的RuntimeException可能导致程序崩溃,然后让读者和作者无法关闭,但那么程序崩溃的事实是不是会关闭呢?
Jen*_*der 23
你的想法是正确的:即使发生了意外的异常,finally块也会关闭资源.
你也是对的,如果这样的异常使整个应用程序崩溃,这是无关紧要的,但是从查看这段代码你无法确定是否是这种情况.可能有其他异常处理程序,捕获该异常,因此将结束逻辑放在finally块中是一种好的和正确的做法.
请注意,仍然可能存在隐藏的错误:如果data.close()抛出异常,result.close()将永远不会被调用.
根据您的环境,有各种各样的风格如何修复错误.
在java 7中,您可以使用try-with-resources
如果您使用的是Spring,可能会有一个类似于JdbcTemplate的正确模板
如果没有这些适用,是的,你将不得不在最终内部尝试/终于.退出丑陋.你绝对应该至少将其提取到评论中建议的方法中.
在概念上更清洁,但在java pre 8中是罗嗦的是实现贷款模式.如果你不碰巧使用scala/clojure/haskell开发人员,那么它可能会比其他任何事情更令人困惑.
这是一个非常简单的原因:它是最安全的方式,在Java 7和try-with-resources之前,即使发现异常,也能保证资源被关闭.
考虑一下如果你这样做了:
try {
// some code, then
resource.close();
} catch (SomeException e) {
// etc
}
Run Code Online (Sandbox Code Playgroud)
如果在资源关闭之前SomeException抛出您的资源,则可能会泄漏资源.把进入,而另一方面,可以保证它不被无论什么事情发生关闭.resource.close()finally
使用Java 7,您可以使用:
try (
final InputStream in = Files.newInputStream(Paths.get("somefile"));
// Others
) {
// work with "in" and others
} catch (Whatever e) {
}
Run Code Online (Sandbox Code Playgroud)
你的资源将被关闭之前 catch.
作为旁注,使用Java 6,关闭资源的最安全方法是使用Guava Closer.
如果程序在此之后终止,则是,这也将关闭I/O资源.
但许多程序不会终止.有一些必须每周7天,每天24小时运行.因此,正确清理资源是必须的.
不幸的是,Java <7仅提供内存的自动清理机制(垃圾收集).使用Java 7,您将获得尝试插入漏洞的新" try-with-resource语句 ".
除非您可以使用此版本,否则您必须自己进行清理.
也就是说,上面的代码仍然是错误的:close()它本身可以抛出一个异常,因此一些I/O资源可能仍然存在.你应该使用像IOUtils.closeQuietly()这样的工具:
Reader reader = null;
try {
reader = ...open...
...use reader...
} finally {
IOUtils.closeQuietly(reader);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2499 次 |
| 最近记录: |