Java8 の Optional 型を返す Generics を使ったメソッドを定義する

公開日: : 最終更新日:2015/01/12 Java ,

Java8 の Optional とガード節 に続いて Java8 の Optional ネタ。今回は Generics を使ったタイプセーフな Optional 型を返すメソッドを定義する方法について。

icatch_2185253176

photo credit: red5standingby via photopin cc

目次

1. Generics を使って Optional クラスのインスタンスを返すメソッドの定義

あるオブジェクトを指定したクラスにキャストして、それを格納した Optional のインスタンスを返すメソッドを定義したかった。タイプセーフにキャストする方法はないものかと検索したら Stack OverflowClass#cast() を使えばいいという記事を見つけた。

キャストの部分を抜き出しておく。

public <T extends Animal> T callFriend(String name, Class<T> type) {
    return type.cast(friends.get(name));
}

Generics の理解が浅いからこういう引数を設ければいいという発想にならなかった。

2. これを使って何がしたいのか

Generics を使ったタイプセーフな Optional 型を返すメソッドを使って何がしたかったのかというと、一時的に何でも格納できる「入れ物」が欲しくなったから。

せっかく Java8 を使っているのだから「取ってきた値が null じゃなかったら○○」みたいな if 文ではなく、Optional を使ってみたかった。お勉強も兼ねて Optional 型を戻り値にしてみよう、という発想からスタートしたもの。言葉だけではよく分からないので以下に実例を載せておく。

3. 「入れ物」クラスの実例

作ったというほどでもないが作ってみた。処理フローは次の通り。

  1. キーとキャストしたい型の Class を受け取る
  2. キーに対応する値を取得して指定の型にキャストする
  3. キャストした値を引数に Optional#ofNullable() を実行してインスタンスを生成する
  4. 生成したインスタンスを return する

コードは次の通り。非常に単純。

/**
 * {@code Optional} を返すタイプセーフなキャッシュクラス。
 * 
 * @author tomoyamkung
 *
 */
public class OptionalCache {

    /**
     * キャッシュに使う {@code Map}。
     * 
     * {@code String} をキーとして、値はどんなクラスでも格納できるように {@code Object} とする。
     * 
     */
    private Map<String, Object> cache;

    /**
     * コンストラクタ。
     * 
     * キャッシュの初期化を行う。
     * 
     */
    public OptionalCache() {
        cache = new HashMap<>();
    }

    /**
     * キャッシュに値を登録する。
     * 
     * @param key 登録する値のキー。
     * @param value 登録する値。
     */
    public <V> void put(String key, V value) {
        Objects.requireNonNull(key, "key は必須。");

        cache.put(key, value);
    }

    /**
     * キャッシュから値を取得する。
     * 
     * @param key 取得する値のキー。
     * @param type キャストする型。
     * @return 取得した値を格納した {@code Optional}。
     */
    public <V> Optional<V> get(String key, Class<V> type) {
        Objects.requireNonNull(key, "key は必須。");

        return Optional.ofNullable(type.cast(cache.get(key)));
    }
}

3-1. Optional#ofNullable() を使っている理由

上記の処理フローの 2. で対応する値が登録されていない場合は cache.get(key) の結果で null が返ってくる。null の可能性がある場合は Optional#ofNullable() を使わないと、値を参照するときに NullPointerException になってしまう。なので、3. では Optional#ofNullable() を使っている。

4. 更新履歴

  • 2014/10/24
    • 初版作成
  • 2015/01/11
    • 文言を修正

5. この記事の内容について

この記事は Javaプログラマーなら習得しておきたい Java SE 8 実践プログラミング を読みながら個人的にまとめたことをメモした内容になっています。

調べ物から記事作成までの全て作業はプライベートな時間に行ったものであり、所属組織のリソースは消費していません。また、記事のアイデアも所属組織に由来していません。

記事の内容が必ずしも正しかったり、最新ではないおそれがあります。参考にされる分には構いませんが、記事の内容を取り入れたことによって発生した損害などの責任は負いません。ご利用は自己判断でお願いいたします。

Javaプログラマーなら習得しておきたい Java SE 8 実践プログラミング

  • 著者Cay S. Horstmann
  • 価格¥ 3,024(2014/10/17 時点)
  • 出版日2014-09-22
  • 商品ランキング24027 位
  • 大型本264 ページ
  • ISBN-104844336673
  • 出版社インプレス

Googleアドセンス用(PC)

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

関連記事

no image

ファイルに関するユーティリティ

ファイルに関するスニペットをいくつか書いた。いつかコピペする日が来ると思うのでメモしておく。 作成

記事を読む

GradleLogoReg

Gradle で Java アプリのプロジェクトを作成して Eclipse にインポートするまでの手順

Mac に SDKMAN! を使って Gradle をインストールしたので、実際にプロジェクトを作成

記事を読む

medium_2055608272

指定した年月の日付を Calendar オブジェクトの一覧で取得する

小ワザです。 業務で、指定した年月の日付を Calendar オブジェクトの一覧で取得する必要があり

記事を読む

no image

画像ファイルのサイズ(縦横じゃなくて容量)を取得するスニペット

File#length で取得できるとは知らなかった。Gist にも登録済み。 /** * 画

記事を読む

no image

ディレクトリに関するユーティリティ

ディレクトリに関するスニペットをいくつか書いた。いつかコピペする日が来ると思うのでメモしておく。

記事を読む

icatch_4610898091-resized

Java8 の Optional とガード節

メソッドの冒頭で条件チェックを行い、条件を満たしていない場合はさっさと return してしまう「ガ

記事を読む

no image

Spark を使って JSON を返すシンプルな API を書いてみた

必要に迫られてモックの API を作成することになった。 大した工数を割けないので使ったことのある

記事を読む

GradleLogoReg

SDKMAN!(GVM) を使って Mac に Gradle をインストールする

長らく Java のアプリ開発には Maven を使ってきたが、時代に取り残されている感じがするので

記事を読む

icatch-thumbnail

レスポンスにサムネイル画像を返す API のサンプル

今回は直接 ImageMagick は関係ありませんが、また画像ネタです。この辺りのことを仕事で扱っ

記事を読む

icatch-upload_1229138273_mini-thumbnail

InputStream に格納されているストリームデータのサイズを取得する

Jersey を使った Web アプリを作成中なんですが、 enctype="multipart/f

記事を読む

Googleアドセンス用(PC)

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


五 + 1 =

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Googleアドセンス用(PC)

icatch-jersey_multi_pathparams
Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format}

icatch-vagrant_box_customize
VagrantのBoxファイルをカスタマイズして独自のBoxファイルを作成する

配布されている Vagrant の Box ファイルを使って検証環境を

icatch-2015-006-1
バリデーションチェックにJava8のOptionalを使ってスマートに書く(自分比)

Web アプリのバリデーションチェックにアノテーションを使うことが増え

icatch-2015-005-1
ユニットテストの偏りを防ぐ命名規則の付け方

ユニットテスト名に以下の命名規則を付けるようにして二ヶ月ぐらい経った。

icatch-2015-004-1
Vagrantで起動したCentOS上のOctopressをホストOSから確認する設定

タイトルの通りだが、Vagrant を使って起動した CentOS に

→もっと見る

PAGE TOP ↑