无法在 'finally' 子句中关闭()流,未初始化 variable/unhandled IOException [Java IO]

Cannot close() stream in 'finally' clause, uninitialized variable/unhandled IOException [Java IO]

所以我在 class 文件中有这个方法,只是试图将 Book 对象写入 aPath(字符串)。 但是,它给了我 'Unhandled IOException',我不确定我是否理解为什么我的 try 块似乎有一个 catch 子句。

所以为了解决这个问题,我尝试在我的方法中添加一个 'throws' 子句,但是一旦我这样做了,它就说 'out' 变量没有被初始化。

有什么方法可以在 finally 子句中关闭流?

    public void writeToFile(String aPath) {
    
        ObjectOutputStream out;
        try {
            out = new ObjectOutputStream(new FileOutputStream(aPath));
            
            out.writeObject(this.book);
        }
        catch(IOException e){
            System.out.println("Error writing to file");
            e.printStackTrace();
        }
        finally {
            out.close(); //unhandled IOException error :(
        }
    }

使用try with resources会处理未初始化资源的问题:

public void writeToFile(String aPath) {
    try (ObjectOutputStream out = 
             new ObjectOutputStream(new FileOutputStream(aPath))) {
        out.writeObject(this.book);
    }
    catch (IOException e) {
        System.out.println("Error writing to file");
        e.printStackTrace();
    }
}

根据 JLS,由 writeObject 调用抛出的 IOException 或由资源的隐式 close() 抛出的 IOException 将在该处理程序中被捕获。

真优雅...


关于,你的尝试:

I want to know why I cannot use out.close() in finally clause.

因为out不一定已经初始化了。例如,如果 IOException 被抛入 new FileOutputStream(...)out 将不会被初始化。要使用显式 finally 使其工作,您需要执行以下操作:

public void writeToFile(String aPath) {
    ObjectOutputStream out = null;
    try {
        out = new ObjectOutputStream(new FileOutputStream(aPath));
        out.writeObject(this.book);
    }
    catch (IOException e) {
        System.out.println("Error opening or writing to file");
        e.printStackTrace();
    }
    finally {
        if (out != null) {
            try {
                out.close();
            }
            catch (IOException e) {
                System.out.println("Error closing file");
                e.printStackTrace();
            }
        }
    }
}

既然你问了....异常处理/压缩可能是个坏主意:

  • 调用方未收到文件写入失败的指示。它会像什么都没发生一样继续执行。

  • 通常不应将堆栈跟踪写入标准输出。如果相关,则应记录堆栈跟踪:

    • 如果这是一个最终用户应用程序,向用户显示堆栈跟踪是令人讨厌的。他们需要的是一条信息丰富的错误消息。将异常/堆栈跟踪单独记录到日志文件可能对安装/配置软件的系统管理员或编写它的程序员有用。
    • 如果这是一项服务,那么写入标准输出的内容可能会丢失。应该记录真正的错误。由于错误的用户输入(可能)导致的事情应该(可能)不被记录。