Java8 の Optional 型を返す Generics を使ったメソッドを定義する
Java8 の Optional とガード節 に続いて Java8 の Optional
ネタ。今回は Generics を使ったタイプセーフな Optional
型を返すメソッドを定義する方法について。
photo credit: red5standingby via photopin cc
目次
- 1. Generics を使って Optional クラスのインスタンスを返すメソッドの定義
- 2. これを使って何がしたいのか
- 3. 「入れ物」クラスの実例
- 4. 更新履歴
- 5. この記事の内容について
1. Generics を使って Optional クラスのインスタンスを返すメソッドの定義
あるオブジェクトを指定したクラスにキャストして、それを格納した Optional
のインスタンスを返すメソッドを定義したかった。タイプセーフにキャストする方法はないものかと検索したら Stack Overflow で Class#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. 「入れ物」クラスの実例
作ったというほどでもないが作ってみた。処理フローは次の通り。
- キーとキャストしたい型の
Class
を受け取る - キーに対応する値を取得して指定の型にキャストする
- キャストした値を引数に
Optional#ofNullable()
を実行してインスタンスを生成する - 生成したインスタンスを
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)
関連記事
-
-
ファイルに関するユーティリティ
ファイルに関するスニペットをいくつか書いた。いつかコピペする日が来ると思うのでメモしておく。 作成
-
-
保存ダイアログを表示させてファイルをダウンロードさせる方法
例えば、ブラウザに表示している画像は右クリックを使ってダウンロードできますが、左クリックから保存ダイ
-
-
SDKMAN!(GVM) を使って Mac に Gradle をインストールする
長らく Java のアプリ開発には Maven を使ってきたが、時代に取り残されている感じがするので
-
-
Gradle で Java アプリのプロジェクトを作成して Eclipse にインポートするまでの手順
Mac に SDKMAN! を使って Gradle をインストールしたので、実際にプロジェクトを作成
-
-
指定した年月の日付を Calendar オブジェクトの一覧で取得する
小ワザです。 業務で、指定した年月の日付を Calendar オブジェクトの一覧で取得する必要があり
-
-
Stream#map()とStream#collect()を使ってListを生成する
Java8 から導入された Stream API も少しずつ慣れてきて、「そういえばこういうパターン
-
-
Functions#compose() を使って Function を合成するサンプル(Java8 との比較付き)
Java8 と GoogleGuava の Function について コードの違いを書いた。 その
-
-
サーブレットでクラスパス上にあるプロパティファイルを参照するスニペット
よく使うわりにはいつも調べているのでいい加減メモすることにした。 "app.proper
-
-
Exec Maven Plugin で maven コマンドでアプリを起動する
packaging タグに "jar" を指定した Maven プロジェクトをコマンドラインから起動
-
-
Java でファイルが1つだけ圧縮された zip を解凍するサンプル
ファイルが1つだけ圧縮された zip を解凍するサンプルです。 単一ファイルが圧縮された zip