概要
Optionalはnullである可能性を明示的に返してくれる便利なコンテナ・オブジェクトです。
if(obj == null)... といったことをしなくてよくなったのは素晴らしいことだと思っています。
考察内容
nullをOptional型で返してSyetem.out.printすると「Optional.empty」が表示されます。
null安全なのは良いけど、WebアプリケーションのView等に表示するわけにはいかないなぁと感じたのがきっかけです。
対応方法として、Optionalを返すのではなく、nullをデフォルト値等に変換してから返してしまえばいいのではないかというのが考えです。
実装例
商品情報を持つItemオブジェクト(WebアプリケーションだとEntity想定)
- name、amountは必須項目なので値は必ず保持しており、descriptionはnullである可能性がある状況を想定。
- descriptionはフィールドとしてはnullを保持するが、アクセサで返す値はデフォルト値として空文字にする。
- これにより、Entityとしてはnullを持つのでDB値と整合性が取れ、利用側のクラス(ここではMain)はデフォルト値(空文字)を扱うことができる。
Item.java
import java.util.Optional;
public class Item {
private String name; // DBで必須項目
private Integer amount; // DBで必須項目
private String description; // DBで任意項目(NULLの可能性がある)
public Item(String name, Integer amount, String description) {
this.name = name;
this.amount = amount;
this.description = defaltStrValue(description);
}
public String name() {
return name;
}
public Integer amount() {
return amount;
}
public String description() {
return Optional.ofNullable(description).orElse("");
}
public String text() {
return "["+ String.format(
"name: %s, amount: %d, description: %s", name, amount, description)
+ "]";
}
}
Main.java
public class Main {
public static void main(String...strings) {
// nullをOptionalで返すと、「Optional.empty」が表示される。
System.out.println(Optional.ofNullable(null));
Item tv = new Item("BRAVIA", 79000, null);
System.out.println(tv.text());
System.out.println("description is " + tv.description());
}
}
Optional.empty
[name: BRAVIA, amount: 79000, description: null]
description is
Webアプリケーションなんかで、modelにそのままentityを渡して表示させると、「Optional.empty」が出てしまうので、アクセサ(Getter)でデフォルト値にしてしまうのが、適切かなぁと思った次第です。
まとめ
- Optionalはnull安全にできる便利なコンテナ・オブジェクトである。
- 利用側で処理せず、「Optional.empty」となってしまうようであれば、デフォルト値を返してしまうのがよさそう。
- フィールドで保持する値(null)とアクセサで返す値(空文字)を分けることで、DB値と利用側で表示する値を区別して扱うことも可能になる。
参考
Qiita - Optionalの正しい使い方
Qiita - 【Java】Optionalの正しい使い方を学ぶ
Qiita - Java 8 "Optional" ~ これからのnullとの付き合い方 ~
Qiita - [Java8] Optionalで脱Exception!