1前書き

JDKで提供されている

機能インタフェース

は、チェックされた例外を処理するための準備が正しくありません。この問題についてもっと知りたいなら、

この記事

をチェックしてください。

この記事では、機能的なJavaライブラリーhttp://www.vavr.io[Vavr]を使ってそのような問題を克服するためのさまざまな方法を見ていきます。

Vavrとその設定方法についての詳細な情報を得るには、リンク:/vavr[この記事]を調べてください。


2

CheckedFunction


を使う

Vavrは、チェックされた例外をスローする機能を持つ

機能的なインタフェース

を提供します。これらの関数は

CheckedFunction0



CheckedFunction1

など、

CheckedFunction8

までです。関数名の末尾の

0、1、…​ 8

は、関数の入力引数の数を示します。

例を見てみましょう。

static Integer readFromFile(Integer integer) throws IOException {
   //logic to read from file which throws IOException
}


IOException

を処理せずに、上記のメソッドをラムダ式の中で使用できます。

List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);

CheckedFunction1<Integer, Integer> readFunction = i -> readFromFile(i);
integers.stream()
 .map(readFunction.unchecked());

ご覧のとおり、標準の

try-catch

メソッドまたはラッパーメソッドがなくても、ラムダ式の中で例外スローメソッドを呼び出すことができます。


Stream

APIでこの機能を使用するときは注意が必要です。例外が発生するとすぐに操作が終了し、残りのストリームは破棄されます。


3ヘルパーメソッドを使う

APIクラスは、前のセクションの例に対するショートカットメソッドを提供します。

List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);

integers.stream()
  .map(API.unchecked(i -> readFromFile(i)));


4リフティングを使う


IOException

を適切に処理するために、ラムダ式の中に標準の

try-catch

ブロックを導入できます。ただし、ラムダ式の簡潔さは失われます。 Vavrの持ち上げは私たちの助けになります。

リフティングは関数型プログラミングからの概念です。部分関数を結果として

Option

を返すtotal関数に持ち上げることができます。

部分関数は、そのドメイン全体に対して定義されている全体関数とは対照的に、そのドメインのサブセットに対してのみ定義されている関数です。サポート範囲外の入力を使用して部分関数が呼び出されると、通常は例外がスローされます。

前のセクションの例を書き換えてみましょう。

List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);

integers.stream()
  .map(CheckedFunction1.lift(i -> readFromFile(i)))
  .map(k -> k.getOrElse(-1));

解除された関数の結果は

Option

で、例外の場合の結果は

Option.None

になります。メソッド

getOrElse()

は、

Option.None

の場合に返す代替値を取ります。


5

Try


を使う

前のセクションのメソッド

lift()

は突然のプログラム終了の問題を解決しますが、実際には例外を飲み込みます。

その結果、私たちの方法の消費者は、何がデフォルト値をもたらしたのかについて見当がつかない。別の方法は

Try

コンテナを使用することです。


Try

は、例外をスローする可能性のある操作を囲むことができる特別なコンテナです。この場合、結果の

Try

オブジェクトは

Failure

を表し、例外をラップします。


Try

を使ったコードを見てみましょう。

List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);

integers.stream()
  .map(CheckedFunction1.liftTry(i -> readFromFile(i)))
  .flatMap(Value::toJavaStream)
  .forEach(i -> processValidValue(i));


Try

コンテナとその使い方の詳細については、

この記事

をチェックしてください。


6. 結論

この簡単な記事では、ラムダ式の例外を処理しながら、問題を回避するためにVavrライブラリの機能を使用する方法を示しました。

これらの機能により、例外をエレガントに処理できますが、細心の注意を払って使用する必要があります。これらのアプローチのいくつかでは、あなたのメソッドの消費者は、それらが明示的に宣言されていないけれども、予期しないチェックされた例外に驚くかもしれません。

この記事のすべての例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/vavr[over on Github]にあります。