我正在寻找Java7的新功能。我发现一个是try-with-resources Statement。任何人都可以告诉我它究竟意味着什么?我们应该使用它的原因和位置,以及我们可以利用此功能的地方?即使try
语句错过了catch
阻止我这也让我感到困惑。
答案 0 :(得分:73)
之所以引入它是因为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
}
}
你注意到丑陋的双重尝试吗?现在使用try-with-resources可以做到这一点:
try (InputStream stream = new MyInputStream(...)){
// ... use stream
} catch(IOException e) {
// handle exception
}
自动调用和 close(),如果它抛出IOException,它将被抑制(如Java Language Specification 14.20.3中所指定)。 java.sql.Connection
也是如此答案 1 :(得分:15)
作为stated in the documentation:
try-with-resources语句是一个声明一个的try语句 或更多资源。资源是必须在之后关闭的对象 程序完成了。 try-with-resources语句 确保在语句结束时关闭每个资源。任何 实现
java.lang.AutoCloseable
的对象,包括所有 实现java.io.Closeable
的对象可以用作 资源。以下示例从文件中读取第一行。它使用了 BufferedReader的实例,用于从文件中读取数据。的BufferedReader 是程序完成后必须关闭的资源 它:
static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } }
在此示例中,try-with-resources中声明的资源 statement是一个BufferedReader。声明声明出现 在try关键字后面的括号内。班级 Java SE 7及更高版本中的BufferedReader实现了该接口 java.lang.AutoCloseable。因为BufferedReader实例是 在try-with-resource语句中声明,它将被关闭 无论try语句是正常还是突然完成
您可以从here了解更多信息。
答案 2 :(得分:7)
在Java中,如果使用输入或输出流等资源,则必须在使用后关闭它。它也可以抛出异常,因此它必须位于try
catch
块中。结束必须在finally
区块内。这是Java 7之前的最小方法。这有几个缺点:
null
finally
必须包含其他try
- catch
虽然前两个主要是语法问题,但最后一个更为关键。因此,如果您使用try-with语句,您的代码将变得更加清晰,最重要的是:您的资源将始终关闭: - )
答案 3 :(得分:6)
优点是您无需显式关闭在try-with-resources语句中定义的资源。 JVM将负责它。它会自动为您关闭这些资源。
开发人员面临的问题通常是构造try-catch-finally块,因为即使在我们关闭资源的finally块中,我们也必须使用try-catch。有各种try-catch-finally语句结构可以帮助解决这个问题但是try-with-resources语句基本上可以帮助您简化编码结构逻辑。
答案 4 :(得分:5)
现在使用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
}
}
在这里,我们可以注意到这个代码非常难看,正如其他答案所指出的那样。
因此Java 7
中的解决方案是引入此try-catch-with-resource
:
try (InputStream stream = new MyInputStream(...)){
// ... use stream
} catch(IOException e) {
// handle exception
}
这种符号肯定比前一种更好,但是我们遇到了问题。如果资源(在这种情况下是 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
}
我们可以注意到这种情况只能用另一条丑陋的代码解决。这就是为什么使用 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
}
请注意,此语法将导致Java版本8或次要的编译时错误
这是更“自然”的写作方式,即使在大多数用例中我们不需要try块范围之外的资源。 唯一的限制是读者变量应该是最终的,或者只是最终的。
答案 5 :(得分:1)
使用资源试用的好处
更易读的代码,易于编写。
自动资源管理。
减少了代码行数。
只需关闭资源就不需要最终阻止。
我们可以在用分号分隔的try-with-resources语句中打开多个资源。例如,我们可以编写以下代码。
在try-with-resources中打开多个资源时,它会以相反的顺序关闭它们以避免任何依赖性问题。您可以扩展我的资源程序来证明这一点。
public void sampleTryWithResource() {
try(Connection dbCon = DriverManager.getConnection("url", "user", "password");
BufferedReader br = new BufferedReader(new FileReader("C://readfile/input.txt"));) {
//...Your Business logic
} catch (Exception e) {
//...Exception Handling
}
}
答案 6 :(得分:-4)
这个怎么样 - 如果在try {}内部初始化资源,它是否会自动关闭?
try {
Scanner scanner = new Scanner(new File(csvFile));
while (scanner.hasNext()) {
// do something
}
scanner.close();
}catch(FileNotFoundException fnfe)
{
System.err.println(fnfe.getLocalizedMessage());
}