問題
次のコードをコンパイル、実行するとどうなりますか。なお、実行時に例外はスローされずコードは正常に実行されるものとします。
public class Main {
public static void main(String[] args) {
MyResource a = new MyResource("ResourceA");
MyResource b = new MyResource("ResourceB");
MyResource c = new MyResource("ResourceC");
try (a; c; b) {
//任意の処理
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.print("finally ");
}
}
}
class MyResource implements AutoCloseable {
String resourceName = null;
MyResource(String resourceName) {
this.resourceName = resourceName;
}
public void close() throws Exception {
System.out.print(resourceName + " is closed. ");
}
}
選択肢
A)finally ResourceB is closed. ResourceC is closed. ResourceA is closed. が出力される
B)何も出力されない
C)ResourceA is closed. ResourceB is closed. ResourceC is closed. finally が出力される
D)finally ResourceA is closed. ResourceC is closed. ResourceB is closed. が出力される
E)finally が出力される
F)finally ResourceC is closed. ResourceB is closed. ResourceA is closed. が出力される
G)ResourceA is closed. ResourceC is closed. ResourceB is closed. finally が出力される
H)ResourceB is closed. ResourceC is closed. ResourceA is closed. finally が出力される
解答
A)finally ResourceB is closed. ResourceC is closed. ResourceA is closed. が出力される
B)何も出力されない
C)ResourceA is closed. ResourceB is closed. ResourceC is closed. finally が出力される
D)finally ResourceA is closed. ResourceC is closed. ResourceB is closed. が出力される
E)finally が出力される
F)finally ResourceC is closed. ResourceB is closed. ResourceA is closed. が出力される
G)ResourceA is closed. ResourceC is closed. ResourceB is closed. finally が出力される
H)ResourceB is closed. ResourceC is closed. ResourceA is closed. finally が出力される
解説
MyResourceクラスは、AutoCloseableを実装しているため、リソースとして扱われます。
以下のように複数のリソースが指定されています。
MyResource a = new MyResource("ResourceA");
MyResource b = new MyResource("ResourceB");
MyResource c = new MyResource("ResourceC");
しかし、try-with-resourceによるリソースのクローズは複数のリソースを指定した場合、クローズは指定と逆順となります。
そのため、try文の (a; c; b)と指定しているため、close()のクローズ順は、b→c→a となります。
その後、すべてクローズ後finallyが実行され、finallyが出力されます。
public class Main {
public static void main(String[] args) {
MyResource a = new MyResource("ResourceA"); //1-1.
MyResource b = new MyResource("ResourceB"); //2-1.
MyResource c = new MyResource("ResourceC"); //3-1.
try (a; c; b) { //4. b→c→aのクローズ順 b:4-1b c:4-1c a:4-1a
//任意の処理
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.print("finally "); //5.
}
}
}
class MyResource implements AutoCloseable {
String resourceName = null; //1-4. 2-4. 3-4.
MyResource(String resourceName) { //1-2. 2-2. 3-2.
this.resourceName = resourceName; //1-3. 2-3. 3-3.
}
public void close() throws Exception { //4-2b 4-2c 4-2a
System.out.print(resourceName + " is closed. "); //4-3b 4-3c 4-3a
}
}
対象資格:Java SE17 認定資格