我正在寻找Java7的新功能.我发现一个是 try-with-resources Statement.任何人都可以告诉我它究竟意味着什么?我们应该使用它的原因和位置,以及我们可以利用此功能的地方?即使是try声明也没有catch阻止让我感到困惑.
mor*_*ano 75
它的引入是因为Java中使用的一些资源(如SQL连接或流)难以正确处理; 例如,在java 6中正确处理InputStream你必须做类似的事情:
InputStream stream = new MyInputStream(...);
try {
// ... use stream
} catch(IOException e) {
// handle exception
} finally {
try {
if(stream != null) {
stream.close();
}
} catch(IOException e) {
// handle yet another possible exception
}
}
Run Code Online (Sandbox Code Playgroud)
你注意到丑陋的双重尝试吗?现在使用try-with-resources可以执行以下操作:
try (InputStream stream = new MyInputStream(...)){
// ... use stream
} catch(IOException e) {
// handle exception
}
Run Code Online (Sandbox Code Playgroud)
并且会自动调用close(),如果它抛出IOException,它将被抑制(如Java语言规范14.20.3中所指定).同样的情况发生了java.sql.Connection中
Ank*_*thi 15
如文档中所述:
try-with-resources语句是一个声明一个或多个资源的try语句.资源是在程序完成后必须关闭的对象.try-with-resources语句确保在语句结束时关闭每个资源.实现的任何对象(
java.lang.AutoCloseable包括实现的所有对象)java.io.Closeable都可以用作资源.以下示例从文件中读取第一行.它使用BufferedReader实例从文件中读取数据.BufferedReader是一个在程序完成后必须关闭的资源:
Run Code Online (Sandbox Code Playgroud)static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } }在此示例中,try-with-resources语句中声明的资源是BufferedReader.声明语句出现在try关键字后面的括号内.Java SE 7及更高版本中的BufferedReader类实现了java.lang.AutoCloseable接口.因为BufferedReader实例是在try-with-resource语句中声明的,所以无论try语句是正常还是突然完成,它都将被关闭
您可以从这里阅读更多内容.
在Java中,如果使用输入或输出流等资源,则必须在使用后关闭它.它也可以抛出异常,因此必须处于try catch阻塞状态.关闭必须在finally块中.这是Java 7之前的最小方法.这有几个缺点:
null在关闭之前检查您的资源是否正确finally必须包含另一个try-catch虽然前两个主要是语法问题,但最后一个更为关键.因此,如果您使用try-with语句,您的代码会变得更加清晰,最重要的是:您的资源将始终关闭:-)
优点是您无需显式关闭在try-with-resources语句中定义的资源.JVM将负责它.它会自动为您关闭这些资源.
开发人员面临的问题通常是构造try-catch-finally块,因为即使在我们关闭资源的finally块中,我们也必须使用try-catch.有各种try-catch-finally语句结构可以帮助解决这个问题但是try-with-resources语句基本上可以帮助您简化编码结构逻辑.
现在Java 9有了更多的语法糖,我们可以在try-catch块外声明资源,但仍然可以正确处理。
让我们以这种Java 6处理资源的方式为例:
InputStream stream = new MyInputStream(...);
try {
// ... use stream
} catch(IOException e) {
// handle exception
} finally {
try {
if(stream != null) {
stream.close();
}
} catch(IOException e) {
// handle yet another possible exception
}
}
Run Code Online (Sandbox Code Playgroud)
在这里我们可以注意到,正如其他答案中指出的那样,此代码非常丑陋。
因此,解决方案Java 7是引入以下内容try-catch-with-resource:
try (InputStream stream = new MyInputStream(...)){
// ... use stream
} catch(IOException e) {
// handle exception
}
Run Code Online (Sandbox Code Playgroud)
这个表示法肯定比以前的表示法好,但是我们有一个问题。如果资源(在这种情况下为strem)先前已经声明过,但是我们要确保在此块中正确处理了资源,则需要这样的技巧:
InputStream stream = new MyInputStream(...)
try (InputStream stream2 = stream) {
// do something with stream being sure that is going to be closed at the end
} catch(IOException e) {
// handle exception
}
Run Code Online (Sandbox Code Playgroud)
我们可以注意到,这种情况只能用另一段丑陋的代码来解决。这就是使用Java 9改进了Try-With-Resources并引入了新语法的原因:
InputStream stream = new MyInputStream(...)
try (stream) {
// do something with stream being sure that is going to be closed at the end
} catch(IOException e) {
// handle exception
}
Run Code Online (Sandbox Code Playgroud)
请注意,此语法将导致Java版本8或次要版本出现编译时错误
即使在大多数用例中,我们不需要try块范围之外的资源,这也是一种“自然”的编写方式。 唯一的限制是reader变量应该有效地是final或just final。