【发布时间】:2015-06-02 18:56:20
【问题描述】:
我正在尝试在 OS X 上使用 Java 8 的简单 try-with-resource 示例。
我看到一些奇怪的行为。首先,以下是我正在运行的代码:
public void test() {
try( FileInputStream fin = new FileInputStream("/tmp/test");
FileOutputStream fout = new FileOutputStream("/tmp/test1")
){
System.out.println("Nothing here");
System.out.println("Nothing here");
}catch (Exception e) {
System.err.println("Error " + e);
}
}
应用程序运行良好,并以预期的两倍打印Nothing here。
当我在调试模式(IntelliJ 想法)下运行它时,执行在FileInputSteam::close() 处暂停两次,然后在FileOutputStream::close() 处暂停,然后在FileInputStream::close() 处再次暂停——为了检查这种行为的来源,我查看了.class通过 jad-gui 文件。它显示以下代码:
public void test()
{
try
{
FileInputStream fin = new FileInputStream("/tmp/test");Throwable localThrowable6 = null;
try
{
FileOutputStream fout = new FileOutputStream("/tmp/test1");Throwable localThrowable7 = null;
try
{
System.out.println("Nothing here");
System.out.println("Nothing here");
}
catch (Throwable localThrowable1)
{
localThrowable7 = localThrowable1;throw localThrowable1;
}
finally {}
}
catch (Throwable localThrowable4)
{
localThrowable6 = localThrowable4;throw localThrowable4;
}
finally
{
if (fin != null) {
if (localThrowable6 != null) {
try
{
fin.close();
}
catch (Throwable localThrowable5)
{
localThrowable6.addSuppressed(localThrowable5);
}
} else {
fin.close();
}
}
}
}
catch (Exception e)
{
System.err.println("Error " + e);
}
}
这更令人困惑。
为什么反编译后的代码没有显示任何调用 FileOutputStream::close() - 这是 jd-gui 的问题吗?
为什么在调试过程中控件会先转到两次 FileInputStream::close()?这是一些错误还是它应该如何工作?
【问题讨论】:
-
这是一个很好的问题。我不知道,但如果我不得不猜测,我会认为 FileOutputStream 在其自己的关闭过程中内部关闭 FileInputStreams。有没有人看过它的来源?您拥有的所有数据都是类,而不是特定实例。
-
@MichaelEricOberlin
FileOutputStream如何以及为什么会关闭它甚至看不到的FileInputStream? -
你的反编译器一定是错的。以下是 IntelliJ 自己的反编译器如何反编译您的代码:gist.github.com/jnizet/6bbd5a1efc994438a3d6
-
@JBNizet - 感谢您的链接。看起来像 JD GUI 的问题。我会进一步调试,看看我是否能弄清楚为什么会有额外的关闭电话。
标签: java debugging java-7 try-with-resources