Java 关闭读写器的异常处理

Java 关闭读写器的异常处理,java,exception,try-catch,Java,Exception,Try Catch,我只是回顾了我们在java类中编写的一些代码。我注意到,在finally块中有一个try/catch用于关闭读卡器,但不关闭编写器。我将复制下面的代码。有人能解释为什么会这样吗?我想更好地理解 public class UsingFiles { public static void main(String[] args) { // open the input stream (from the file of this program) BufferedReader reader

我只是回顾了我们在java类中编写的一些代码。我注意到,在finally块中有一个try/catch用于关闭读卡器,但不关闭编写器。我将复制下面的代码。有人能解释为什么会这样吗?我想更好地理解

public class UsingFiles {
public static void main(String[] args) {
    // open the input stream (from the file of this program)
    BufferedReader reader = null;
    PrintWriter writer = null;
    try {
        reader = new BufferedReader(new FileReader("./src/UsingFiles.java"));
        writer = new PrintWriter("reverseFile.txt");
        // String line;
        // while ((line = reader.readLine()) != null) {
        // System.out.println(line);
        // }
        // print the file in reverse order
        // use recursion
        reverseFile(reader, writer);
    } catch (FileNotFoundException e) {
        System.out.println("Couldn't open the file!");
    } catch (IOException e) {
        System.out.println("Problem reading the file");
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                System.out.println("Couldn't close the reader");
            }
        }
        if (writer != null) {
            writer.close();
        }
    }
}

private static void reverseFile(BufferedReader reader, PrintWriter writer)
        throws IOException {
    String line = reader.readLine();
    if (line != null) {
        reverseFile(reader, writer);
        writer.println(line);
    }
}

我可以想到两种可能性:

  • 这是疏忽
  • close()
    的两个调用都会引发异常。如果第一个抛出异常,第二个将被跳过——当然,除非第一个被包装在它自己的
    try
    /
    catch
    块中。第二个不需要
    try
    /
    catch
    块,因为如果失败,将不会跳过后续代码
  • 在“现实世界”中,我会说答案是#1。我认为#2不太可能的原因是,即使无法关闭某些流,通常也会有其他代码需要执行。如果
    catch
    块未捕获异常(或重新引发其他异常),则情况尤其如此,因为
    finally
    块中的新异常将替换原始异常,并且您永远不会知道它发生了

    更新


    正如另一个答案所指出的,
    PrintWriter.close()
    实际上不会抛出
    IOException
    ,即使父接口
    Writer
    声明
    close()
    可以抛出
    IOException
    。所以这可能是一个更好的解释。

    我可以想到两种可能性:

  • 这是疏忽
  • close()
    的两个调用都会引发异常。如果第一个抛出异常,第二个将被跳过——当然,除非第一个被包装在它自己的
    try
    /
    catch
    块中。第二个不需要
    try
    /
    catch
    块,因为如果失败,将不会跳过后续代码
  • 在“现实世界”中,我会说答案是#1。我认为#2不太可能的原因是,即使无法关闭某些流,通常也会有其他代码需要执行。如果
    catch
    块未捕获异常(或重新引发其他异常),则情况尤其如此,因为
    finally
    块中的新异常将替换原始异常,并且您永远不会知道它发生了

    更新


    正如另一个答案所指出的,
    PrintWriter.close()
    实际上不会抛出
    IOException
    ,即使父接口
    Writer
    声明
    close()
    可以抛出
    IOException
    。所以这可能是一个更好的解释。

    它实际上应该关闭


    无论何时使用系统上的资源,最好关闭一个有权访问它的对象。

    它实际上应该关闭


    无论何时使用系统上的资源,最好关闭有权访问该资源的对象。

    如果使用“资源试用”,则无需在“最终”块的“试用”块中关闭读取器

    try(reader = new BufferedReader(new FileReader("./src/UsingFiles.java"))
    {
    
    }
    
    catch(Exception e)
    {
    }
    

    如果您正在使用try with resource,则无需关闭finally块的try块中的读取器

    try(reader = new BufferedReader(new FileReader("./src/UsingFiles.java"))
    {
    
    }
    
    catch(Exception e)
    {
    }
    

    我相信其意图是试图关闭作者,即使读者未能关闭。如果关闭读卡器引发IOException,您将永远不会执行finally块的其余部分。

    我相信其目的是尝试关闭写入程序,即使读卡器未能关闭。如果关闭读卡器会引发IOException,您将永远不会执行finally块的其余部分。

    这是因为PrintWriter在关闭()期间从不引发异常。见API。这个

                try {
                    writer.close();
                } catch(IOException e) {
                    System.out.println("Couldn't close the writer");
                }
    

    将导致编译器错误:IOException的捕获块不可访问。从不从try语句体引发此异常,这是因为PrintWriter在close()期间从不引发异常。见API。这个

                try {
                    writer.close();
                } catch(IOException e) {
                    System.out.println("Couldn't close the writer");
                }
    
    将导致编译器错误:IOException的捕获块不可访问。决不会从try语句体引发此异常