简体   繁体   中英

Order of execution of Closeable and AutoCloseable close() methods

Can someone please explain to me what is happening here and in which order?. The output doesn't make any sense to me.

The output is T 1 IOE F.

The code is:

import java.io.Closeable;
import java.io.IOException;

public class TestRes {
    public static void main(String[] args) {
    try (
            MyResource11 r1 = new MyResource11();
            MyResource21 r2 = new MyResource21();
            ) 
        {
            System.out.print("T ");
        } catch (IOException ioe) {
            System.out.print("IOE ");
        } finally {
            System.out.print("F ");
        }
    }
}

class MyResource11 implements AutoCloseable {
    public void close() throws IOException {
        System.out.print("1 ");
    }
}

class MyResource21 implements Closeable {
    public void close() throws IOException {
        throw new IOException();
    }
}

try-with-resources closes the resources in the opposite order to the order they were declared in. So that code:

  1. Prints T
  2. The try-with-resources statement attempts to close r2
  3. That throws an exception
  4. The try-with-resources statement successfully closes r1 , which outputs 1
  5. The exception block is run (for the exception from r2 ) and outputs IOE
  6. The finally block is run, outputting F

It's worth reading through the try-with-resources part of the JLS , which includes code examples of an unravelled try-with-resources statement (eg, the equivalent code with just try / catch / finally ). From that section:

Resources are closed in the reverse order from that in which they were initialized. A resource is closed only if it initialized to a non-null value. An exception from the closing of one resource does not prevent the closing of other resources. Such an exception is suppressed if an exception was thrown previously by an initializer, the try block, or the closing of a resource.

Your code is shortcut for

public static void main(String[] args) {
    try {
        MyResource11 r1 = new MyResource11();
        try {
            MyResource21 r2 = new MyResource21();
            try {
                System.out.print("T ");
            } finally {
                r2.close();
            }
        } finally {
            r1.close();
        }
    } catch (IOException ioe) {
        System.out.print("IOE ");
    } finally {
        System.out.print("F ");
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM