是否接受在 try 块中关闭资源?

Is closing resources in try block accepted?

关于 Java 的初学者书籍中包含以下代码。这本书也很好地解释了异常,并且由于我了解异常是如何工作的,所以我对以下代码有疑问。

出于某种原因,如果 FileWriter class 抛出异常,writer.close() 将不会被执行。因此我认为关闭 writer 对象的最佳位置是在 finally 块中。甚至在此之前,我已经看到许多这样编写的代码,其中资源将在 try 块本身中关闭。我认为这样做没有意义。只有在没有异常的情况下,资源才会被关闭。

我错了吗? java 中关闭资源的最佳方法是什么。我们不应该编写如下代码吗?

 public static void main(String[] args) {

       try{
         FileWriter writer = new FileWriter("file.txt");
         writer.write("i am writing");
         writer.close();
       }catch(IOException e){
           ex.printStackTrace();
       }

    }

如果您使用的是 Java 7,最好的方法是使用 try with resource。参见 https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

 try (FileWriter writer = new FileWriter("file.txt")) {
   writer.write("i am writing");
 }

我同意@cyber-rookie 的观点,最好在 finally 块中关闭资源。

Java 7引入"try-with-resources"以减少编程错误...

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

您现在可以写...

    try (FileWriter writer = new FileWriter("file.txt")) {
        writer.write("i am writing");
    } catch (IOException e) {
        e.printStackTrace();
    }

编译器会在块的末尾为您添加额外的代码来关闭编写器

你是对的,资源应该在 finally 块中关闭。

java 7 开始,您也可以使用 try-with-resource 作为 :

try (BufferedReader br =
               new BufferedReader(new FileReader(path))) {
    return br.readLine();
}

因为BufferedReader实例是在try-with-resource语句中声明的,如果这些资源实现AutoCloseable界面。

根据我的经验,我们会利用 try-catch 的 finally 子句:

public static void main(String[] args) {

    FileWriter writer = null;
    try {
        writer = new FileWriter("file.txt");
        writer.write("i am writing");

    } catch (IOException ex) {
        ex.printStackTrace();

    } finally {
        try {
            if (writer != null)
                writer.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }
}

PS: 将this放在单独的方法中并抛出异常,让class使用这个处理异常。

对在尝试使用资源块时添加多个资源的评论的回答:

try(FileWriter writer = new FileWriter("file.txt"); BufferedReader reader = new BufferedReader(new FileReader("file.txt"))){
        // you can put many AUTOCLOSEABLE objects in try with resource. Just seperate them with ";"  
    } catch (IOException e) {
        e.printStackTrace();
    }

在工作中(Java 6),我们关闭 TRY 块中的资源,然后也在 FINALLY 块中进行防御性关闭。

BufferedReader bufferedReader;
try {
  //initialize and do something with the bufferedReader
   bufferedReader.close();
} catch (FileNotFoundException ex) {
    // notify the user 
} catch (IOException ex) {
    // notify the user 
} finally {
    if (bufferedReader != null) {
        try {
           //defensive close
            bufferedReader.close();
        } catch (IOException ex) {
            // this will be thrown if bufferedReader is already closed (in Try block, so can be leave to blank

        }
    }
}