はじめに
例外処理を行う際,try-catch構文が利用可能ですが,scala.util.Tryを利用すると関数型っぽい実装をすることができます.
Javaでは,Tryクラスは利用できませんが,例外内容に関心がない場合,Optionalクラスを利用することが可能です.そこで,この記事では,Javaで例外ベースのAPIをOptionalベースのAPIに変換する方法について述べます.
この記事の対象読者は次のような人です.
- Scalaを習得している人
- Javaに馴染みがない人
例外ベースのAPIをOptionalベースのAPIに変換する方法
メソッドの中ででtry-catchを隠蔽し,クライアントに対してOptionalベースのインタフェースを提供します.
    // 時間を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から取得し,表示するプログラムを次の2通りの方法で実装しました.
- 例外ベース
- Optionalベース
例外ベースのプログラム
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ベースのインタフェースに見えます.
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();
    }
}
おわりに
もっとスマートなやり方あったら,コメントお願いします.