try-with-resource 关闭序列:FileInputStream 关闭执行了三次
try-with-resource close sequence : FileInputStream close executed three times
我正在尝试一个简单的 try-with-resource
示例,在 OS X 上使用 Java 8。
我看到一些奇怪的行为。首先,下面是我运行ning:
的代码
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 idea)时,执行在 FileInputSteam::close()
处暂停两次,然后在 FileOutputStream::close()
处暂停,然后再次在 FileInputStream::close()
处暂停 - 检查源这种行为,我通过 jad-gui 查看了 .class
文件。它显示以下代码:
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()
?这是一些错误还是它应该如何工作?
查看@jb-nizet 的评论,您的反编译器没有显示正确的内容,这解释了您的问题 1。
对于问题 2,请查看调试器中的 Stream.path 变量。在我的系统上,这不是您的 Streams openend,而是 Java 8 个内部文件,例如“/opt/Oracle_Java/jdk1.8.0_40/jre/lib/tzdb.dat”,“/opt/Oracle_Java/jdk1.8.0_40/jre/lib/meta-index" 和 class 本身。但是我只有一个输入流“/tmp/test”的调用和一个输出流“/tmp/test1”的调用。
我正在尝试一个简单的 try-with-resource
示例,在 OS X 上使用 Java 8。
我看到一些奇怪的行为。首先,下面是我运行ning:
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 idea)时,执行在 FileInputSteam::close()
处暂停两次,然后在 FileOutputStream::close()
处暂停,然后再次在 FileInputStream::close()
处暂停 - 检查源这种行为,我通过 jad-gui 查看了 .class
文件。它显示以下代码:
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()
?这是一些错误还是它应该如何工作?
查看@jb-nizet 的评论,您的反编译器没有显示正确的内容,这解释了您的问题 1。
对于问题 2,请查看调试器中的 Stream.path 变量。在我的系统上,这不是您的 Streams openend,而是 Java 8 个内部文件,例如“/opt/Oracle_Java/jdk1.8.0_40/jre/lib/tzdb.dat”,“/opt/Oracle_Java/jdk1.8.0_40/jre/lib/meta-index" 和 class 本身。但是我只有一个输入流“/tmp/test”的调用和一个输出流“/tmp/test1”的调用。