Help us understand the problem. What is going on with this article?

try-with-resources 構文に catch(Exception e) とか catch(IOException e) は必須じゃない

More than 3 years have passed since last update.

close()呼び出しを保証するtry-with-resources構文

Java6以前では以下のようにtry-finallyを使って書いていたclose()処理

Closeable r = null;
try {
  // リソースを確保
  r = getResource();
  // リソースを使用
  r.use();
} finally {
  if (r != null) r.close();
}

ですが、Java7からは以下のような書き方で大変スマートになっています。

// リソースを確保
try (Closeable r = getResource()) {
  // リソースを使用
  r.use();
}

ご存じ、try-with-resources構文です。

Closeable.close()IOExceptionを投げる

さて上記のコード片ですが、実際のプログラミングをしてみるとある重要な点が省略されていることに気付きます。そう、IOExceptionが投げ出されるのを処理していないのです。特にtry-with-resources構文を使った後者のコード、getResource()use()IOExceptionを投げないとしても全体としてはIOExceptionを投げます。なぜなら、糖衣構文で見えていないけれどもclose()呼び出しがあるから。close()IOExceptionを投げるのでそれを処理する必要があるのです。

つまり後者は実際には、

// リソースを確保
try (Closeable r = getResource()) {
  // リソースを使用
  r.use();
} catch (IOException e) {
  // 適切な処理
}

という形でなくてはいけないのです。もしくはthrows IOExceptionを付けてさらに上位へ投げるか。どちらにしろ、もともとの触れ込みから期待していたよりも若干ノイズの多いコードになります。
と、ここまではtry-with-resources構文を一度でも使ったことのある方ならすでにお気付きのことかと思います。

IOExceptionを投げないclose()を書いたっていい

さてここからが本題。
catchthrowsも使うことなく、次のような単純なコードを成立させることもできるんですよというお話。

// リソースを確保
try (MyResource r = getResource()) {
  // リソースを使用
  r.use();
}

close()が必ず成功するようなCloseable/AutoCloseableクラスというのはありえるわけです。で、そういうクラスを自作する際にCloseableを実装しつつ

public class MyResource implements Closeable {
  public void close() {
    // 必ず成功するクローズ処理
  }
}

と、throws IOExceptionなしのclose()を書くわけです。throws IOExceptionなしでもインターフェース実装は成立しています。そして、このクラスをリソースとするならば

// リソースを確保
try (MyResource r = getResource()) {
  // リソースを使用
  r.use();
}

は検査例外を吐かないものとなります。

気が付いてみれば当たり前のことなのですが、IDEを使っていると最初からthrows IOExceptionが自動的に記述されてしまうため、不要なのに付けっぱなしになり結果として不要なcatchを強要されてしまうこと、まれによくありそうなので注意喚起まで。

yuba
全然わからない 俺たちは雰囲気でコードを書いている
http://cs.hatenablog.jp/
m3dev
インターネット、最新IT技術を活用し日本・世界の医療を改善することを目指します
https://m3.recruitment.jp/engineer/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした