try-with-resources文の基本

# はじめに
・try-with-resources文を使う場合と使わない場合の記述例を示します。
・try-with-resources文を理解するために有効なウェブサイトへのリンクを提供します。
・try-with-resources文はJavaSE7以降で使用可能です。
・try-with-resources文が利用できるクラスは、AutoCloseableインタフェースおよびそのサブインタフェースであるCloseableインタフェースの実装クラスに限られます。

# try-with-resources文の記述例
### try-with-resources文を使わない場合

```java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TryWithResources {
    public static void main(String[] args) {

        String inFilePath = "D:\\A.txt";
        String outFilePath = "D:\\C.txt";

        FileInputStream in = null;
        FileOutputStream out = null;

        try {
            in = new FileInputStream(inFilePath);
            out = new FileOutputStream(outFilePath);
            int c;

            // データをコピーする
            while ((c = in.read()) != -1) {
                out.write(c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
```

ポイント
１．finally句がなくてもコンパイルエラーにはならないので、リソース開放漏れの危険性がある。
２．try句とfinally句の両方で同じリソースを指し示すことが必要なので、変数はtry-catch-finallyの外側で宣言する。
３．finally句のcloseメソッド呼出でIOExceptionの可能性があるため、try-catchのネストが必要。

### try-with-resources文を使う場合

```java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TryWithResources {
    public static void main(String[] args) {

        String inFilePath = "D:\\A.txt";
        String outFilePath = "D:\\C.txt";

        try (FileInputStream in = new FileInputStream(inFilePath);
                FileOutputStream out = new FileOutputStream(outFilePath)) {
            int c;

            // データをコピーする
            while ((c = in.read()) != -1) {
                out.write(c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
```
ポイント
１．基本的にリソースは自動開放。[^1]
[^1]: [try-with-resourcesでリソース解放されないパターン](http://qiita.com/nesheep5/items/6a68d862c5902e5994a4)

２．変数のスコープはtry句に限られる。
３．close時の例外は基本的には考慮不要。


# 参考サイト
[Oracle Java SE Documentation try-with-resources文](http://docs.oracle.com/javase/jp/7/technotes/guides/language/try-with-resources.html)
[TASK NOTES 【Java】try-with-resources構文について](http://www.task-notes.com/entry/20150504/1430708400)
[try-catch-finally、try-with-resources、そして発生した例外たち](http://qiita.com/c-cho/items/a5ba13aaebb91bab98ab)


# ちなみに
FileInputStreamなどのクラスはfinalizeメソッドの中でcloseを呼出しているため、リソース開放漏れのバグには気づきにくい（起こりにくい）のです。ただし、開放をGCに任せるのは非効率だしお作法としてよろしくないので、try-with-resourcesを利用しましょう。

```java:FileInputStream.java
package java.io;

import java.nio.channels.FileChannel;
import sun.nio.ch.FileChannelImpl;


public
class FileInputStream extends InputStream
{

===========================省略===========================

    /**
     * Closes this file input stream and releases any system resources
     * associated with the stream.
     *
     * <p> If this stream has an associated channel then the channel is closed
     * as well.
     *
     * @exception  IOException  if an I/O error occurs.
     *
     * @revised 1.4
     * @spec JSR-51
     */
    public void close() throws IOException {
        synchronized (closeLock) {
            if (closed) {
                return;
            }
            closed = true;
        }
        if (channel != null) {
           channel.close();
        }

        fd.closeAll(new Closeable() {
            public void close() throws IOException {
               close0();
           }
        });
    }

===========================省略===========================

    /**
     * Ensures that the <code>close</code> method of this file input stream is
     * called when there are no more references to it.
     *
     * @exception  IOException  if an I/O error occurs.
     * @see        java.io.FileInputStream#close()
     */
    protected void finalize() throws IOException {
        if ((fd != null) &&  (fd != FileDescriptor.in)) {
            /* if fd is shared, the references in FileDescriptor
             * will ensure that finalizer is only called when
             * safe to do so. All references using the fd have
             * become unreachable. We can call close()
             */
            close();
        }
    }
}
```