我让Eclipse发出以下警告:
Potential resource leak: '<unassigned Closeable value>' may not be closed
对于以下代码段中的表达式new BufferedWriter(...)
:
boolean useStdout = askUserWhetherToUseStdout();
Writer writer = useStdout ? new OutputStreamWriter(System.out) : new BufferedWriter(new FileWriter(new File(askUserForFilename())));
try {
writer.write("Hello World!");
}
finally {
writer.close();
}
这是假阳性吗?我理解整个Writer
的方式是,任何作家都会关闭其底层作家。在我的情况下,writer
将封装新的缓冲写入程序(进而封装文件写入程序(,因此关闭writer
不应该泄露与缓冲写入程序或其底层写入程序相关的任何资源?
我在这里错过了什么?
根据更新的问题编辑的答案:
这是一个基于三元运算符使用的虚假警告。如果操作的右侧没有激发,则不会创建BufferedWriter
,也不会出现资源泄漏。因此,警告所描述的事实上是不可能的。然而,如果你想"处理"它,只需将编写器的创建移动到你的try块中即可。
boolean useStdout = askUserWhetherToUseStdout();
Writer writer = null;
try {
writer = useStdout ? new OutputStreamWriter(System.out)
: new BufferedWriter(new FileWriter(new File(
askUserForFilename())));
writer.write("Hello World!");
} finally {
if (writer != null)
writer.close();
}
如果writer.write("Hello World!");
抛出异常,则永远不会调用writer.close()
。
尝试将其包装到Try-catch块中(可能利用了自动关闭功能,请参阅http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)。
你能检查一下这个代码是否给你警告吗?若并没有,那个么在创建编写器时可能并没有处理IOException,这也应该在try块中完成。
boolean useStdout = askUserWhetherToUseStdout();
Writer writer = null;
try {
writer = useStdout ? new OutputStreamWriter(System.out)
: new BufferedWriter(new FileWriter(new File(
askUserForFilename())));
writer.write("Hello World!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
您也可以使用带有资源的try,它将在try块后自动关闭资源流。
boolean useStdout = askUserWhetherToUseStdout();
try (Writer writer = useStdout ? new OutputStreamWriter(System.out)
: new BufferedWriter(new FileWriter(new File(
askUserForFilename())))) {
writer.write("Hello World!");
} catch (IOException e) {
e.printStackTrace();
}