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

Java 是否接受关闭try块中的资源?,java,exception,io,Java,Exception,Io,一本关于Java的初学者书中有以下代码。这本书也很好地解释了异常,因为我理解了异常是如何工作的,所以我对下面的代码提出了一个问题 出于某种原因,若FileWriter类抛出异常,writer.close()将不会执行。因此,我认为关闭writer对象的最佳位置是finally块。在此之前,我已经看到许多这样编写的代码,其中资源将在try块中关闭。我认为这样做没有意义。只有在没有异常的情况下,资源才会关闭 我错了吗?在java中关闭资源的最佳方法是什么。我们是否应该永远不要编写如下代码 publ

一本关于Java的初学者书中有以下代码。这本书也很好地解释了异常,因为我理解了异常是如何工作的,所以我对下面的代码提出了一个问题

出于某种原因,若FileWriter类抛出异常,
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();
       }

    }

如果您使用的是Java7,最好的方法是使用try with resource。看


我同意@cyberrookie的观点,最好在最后一个区块关闭资源

Java7引入了“资源试用”以减少编程错误

你现在可以写

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

编译器将添加额外的代码,以便在块的末尾为您关闭编写器

如果您是对的,则应在
最后
块中关闭资源

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

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

因为
BufferedReader
实例是在
try with resource
语句中声明的,如果这些资源实现了
自动关闭
接口,则无论
try
语句是正常完成还是突然完成,它都将关闭。

根据我的经验,我们将使用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:将其放置在单独的方法中并引发异常,让使用此方法的类处理异常。

回答注释以在“尝试使用”资源块中添加多个资源:

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();
    }
在工作(Java6)时,我们关闭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

        }
    }
}

您是正确的,最好在finally块中关闭writer对象,但是,由于此writer对象是try-catch的一部分,因此无法在finally块中访问它。为此,您需要在try块之外声明变量。您是正确的,正确的位置是final。当然,这可能会在决赛中引发另一个例外;所以有些人不喜欢这样。顺便说一句:现在,你应该使用try with resources Java 7,你也可以使用try with resources如果我有多个资源要关闭,那该怎么办?@desirepg-你可以用分号分隔,例如。。。try(Resource res1=new-ClosableResource(…);Resource res2=new-ClosableResource(…){…}看来我落后了,java7现在有了一个更干净的方法来处理这个问题。为什么不只在内部try块中执行close()?@Bret-因为在try块中使用bufferedReader时,可能会出现异常,使bufferedReader.close()在未执行try块的情况下,这是关闭finally块的位置。如果将其从“try”块中移除,它将在“finally”块中执行。如果抛出异常,它将在第二个catch块中处理,对吗?如果两个都保留在中,那么如果第一个有效(由于正常操作),它将在finally块中再次调用,这将始终引发异常(并处理它),因为它已经关闭过一次(假设close的实现总是在它已经关闭时引发异常…)
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

        }
    }
}