下面是一个简化的示例,它将导致Eclipses Java系统为表达式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
不应泄漏与缓冲编写器相关的任何资源,或者反过来,它的底层编写器?
我在这里缺少什么?
答案 0 :(得分:2)
根据更新后的问题编辑回答:
这是一个虚假的警告 - 基于使用三元运算符。如果操作的右侧没有触发,那么将不会创建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();
}
答案 1 :(得分:1)
如果writer.write("Hello World!");
抛出异常,则永远不会调用writer.close()
。
尝试将其包装到try-catch块中(可能使用自动关闭功能,请参阅http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)。
答案 2 :(得分:1)
你能检查一下这段代码是否会给你警告吗?如果没有那么你可能在创建编写器时没有处理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-with-resources,它会在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();
}