无法在 '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();
}
}
}
}
既然你问了....异常处理/压缩可能是个坏主意:
调用方未收到文件写入失败的指示。它会像什么都没发生一样继续执行。
通常不应将堆栈跟踪写入标准输出。如果相关,则应记录堆栈跟踪:
- 如果这是一个最终用户应用程序,向用户显示堆栈跟踪是令人讨厌的。他们需要的是一条信息丰富的错误消息。将异常/堆栈跟踪单独记录到日志文件可能对安装/配置软件的系统管理员或编写它的程序员有用。
- 如果这是一项服务,那么写入标准输出的内容可能会丢失。应该记录真正的错误。由于错误的用户输入(可能)导致的事情应该(可能)不被记录。
所以我在 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();
}
}
}
}
既然你问了....异常处理/压缩可能是个坏主意:
调用方未收到文件写入失败的指示。它会像什么都没发生一样继续执行。
通常不应将堆栈跟踪写入标准输出。如果相关,则应记录堆栈跟踪:
- 如果这是一个最终用户应用程序,向用户显示堆栈跟踪是令人讨厌的。他们需要的是一条信息丰富的错误消息。将异常/堆栈跟踪单独记录到日志文件可能对安装/配置软件的系统管理员或编写它的程序员有用。
- 如果这是一项服务,那么写入标准输出的内容可能会丢失。应该记录真正的错误。由于错误的用户输入(可能)导致的事情应该(可能)不被记录。