Given:



class ImageScanner implements AutoCloseable {

    public void close() throws Exception {
        System.out.print("Scanner closed. ");
    }

    public void scanImage() throws Exception {
        System.out.print("Scan.");
        throw new Exception("Unable to scan. ");
    }
}

class ImagePrinter implements AutoCloseable {

    public void close() throws Exception {
        System.out.print("Printer closed. ");
    }

    public void printImage() {
        System.out.print("Print.");
    }
}

and this code fragment:

try (ImageScanner ir = new ImageScanner();
        ImagePrinter iw = new ImagePrinter()) {
    ir.scanImage();
    iw.printImage();
} catch (Exception e) {
    System.out.print(e.getMessage());
}

What is the result?

A.

Scan.Printer closed. Scanner closed. Unable to scan.

B.

Scan.Scanner closed. Unable to scan.

C.

Scan. Unable to scan.

D.

Scan. Unable to scan. Printer closed.

題解

程式第32行,呼叫ImageScanner物件的scanImage方法,會先輸出「Scan.」然後再拋出訊息為「Unable to scan. 」的Exception,這個Exception在try-with-resources會被接住,在離開try的區塊進入catch區塊前,會先自動呼叫ImagePrinter物件的close方法,輸出「Printer closed. 」,再自動呼叫ImageScanner物件的close方法,輸出「Scanner closed. 」。因為ImageScanner物件比ImagePrinter物件還要早宣告與實體化出來,基於try-with-resources結構中的資源為先進後出的特性,ImagePrinter物件會比ImageScanner物件還要早被關閉。

在catch區塊中,會輸出「Unable to scan. 」。