Javaのtry-catchをOptionalで書き直す

# はじめに
例外処理を行う際，try-catch構文が利用可能ですが，scala.util.Tryを利用すると関数型っぽい実装をすることができます．

Javaでは，Tryクラスは利用できませんが，例外内容に関心がない場合，Optionalクラスを利用することが可能です．そこで，この記事では，Javaで例外ベースのAPIをOptionalベースのAPIに変換する方法について述べます．

この記事の対象読者は次のような人です．

- Scalaを習得している人
- Javaに馴染みがない人

# 例外ベースのAPIをOptionalベースのAPIに変換する方法
メソッドの中ででtry-catchを隠蔽し，クライアントに対してOptionalベースのインタフェースを提供します．

```java
    // 時間をWebAPIから取得するメソッド
    public static Optional<String> getTime() {
        try {
            // 接続先URLや接続方法を設定する．
            URL url = new URL("http://api.aoikujira.com/time/get.php");
            ......
            ......
            return Optional.of(time.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return Optional.empty();
    }
```

# サンプルプログラム
現在時刻をWebAPIから取得し，表示するプログラムを次の２通りの方法で実装しました．

- 例外ベース
- Optionalベース

## 例外ベースのプログラム
```java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Main {
    public static void main(String[] args) {
        System.out.println(getTime());
    }

    // 時間をWebAPIから取得するメソッド
    private static String getTime() {
        try {
            // 接続先URLや接続方法を設定する．
            URL url = new URL("http://api.aoikujira.com/time/get.php");
            HttpURLConnection http = (HttpURLConnection) url.openConnection();
            http.setRequestMethod("GET");
            http.connect();

            // 接続先から文字列を読み込む．
            BufferedReader reader = new BufferedReader(new InputStreamReader(http.getInputStream()));
            StringBuilder time = new StringBuilder();
            String line = "";
            while((line = reader.readLine()) != null)
                time.append(line);

            return time.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            reader.close();
        }

        return "";
    }
}
```

## Optionalベースのプログラム
getTime()メソッドがOptional型を返すように書き換えました．メインルーチン(mainメソッド)からすると，getTime()メソッドはOptionalベースのインタフェースに見えます．

```java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Optional;

public class Main {
    public static void main(String[] args) {
        System.out.println(getTime().orElse(""));
    }

    // 時間をWebAPIから取得するメソッド
    private static Optional<String> getTime() {
        try {
            // 接続先URLや接続方法を設定する．
            URL url = new URL("http://api.aoikujira.com/time/get.php");
            HttpURLConnection http = (HttpURLConnection) url.openConnection();
            http.setRequestMethod("GET");
            http.connect();

            // 接続先から文字列を読み込む．
            BufferedReader reader = new BufferedReader(new InputStreamReader(http.getInputStream()));
            StringBuilder time = new StringBuilder();
            String line = "";
            while((line = reader.readLine()) != null)
                time.append(line);
            reader.close();

            return Optional.of(time.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            reader.close();
        }

        return Optional.empty();
    }
}
```

# おわりに
もっとスマートなやり方あったら，コメントお願いします．