19.

Java で null または空文字を判定する|isBlank と Objects の使い方

編集
この記事の要点
  • Java 11 以降は s == null || s.isBlank() の 1 行でほぼ足りる
  • isEmpty() は「長さ 0」、isBlank()「空白だけ」も含む
  • s.equals("")snull だと落ちる。順序を逆にするか Objects を使う
  • null と空文字は別物。DB では NULL'' の検索条件が変わる
  • そもそも null を返さない設計にする。空文字か Optional に寄せる

基本の判定

String s = getValue();

// null または長さ 0
if (s == null || s.isEmpty()) { }

// null または空白だけ(Java 11 以降)
if (s == null || s.isBlank()) { }

// Java 10 以前
if (s == null || s.trim().isEmpty()) { }

// null チェックを先に書く(&& は短絡評価なので安全)
// if (s.isEmpty() || s == null)     ← 逆にすると NullPointerException

||左が真なら右を評価しませんs == null を必ず先に書いてください。

isEmpty と isBlank の違い

isEmpty()isBlank()trim().isEmpty()
""truetruetrue
" "(半角空白)falsetruetrue
" "(全角空白)falsetruefalse
"\t\n"falsetruetrue
"abc"falsefalsefalse
nullNullPointerException
String zenkaku = " ";                       // 全角スペース

System.out.println(zenkaku.isEmpty());       // false
System.out.println(zenkaku.isBlank());       // true   Unicode の空白を判定する
System.out.println(zenkaku.trim().isEmpty()); // false  trim は U+0020 以下しか削らない
System.out.println(zenkaku.strip().isEmpty()); // true  strip は Unicode 対応

日本語の入力フォームでは全角スペースが必ず混ざります。trim() ではなく isBlank()strip() を使ってください。

null 安全に書く

String s = null;

// 落ちる
// if (s.equals("")) { }

// 定数を左に置く
if ("".equals(s)) { }                  // false(例外にならない)

// Objects を使う
if (Objects.equals(s, "")) { }         // false

// 既定値を用意する
String value = Objects.requireNonNullElse(s, "");
String value2 = Objects.toString(s, "");        // null なら ""
String value3 = Objects.requireNonNullElseGet(s, () -> loadDefault());

// 必須の引数は早い段階で落とす
public void run(String name) {
    Objects.requireNonNull(name, "name は必須です");
}

判定用のメソッドを 1 つ作る

public final class Strings {
    private Strings() {}

    /** null か空文字なら true */
    public static boolean isEmpty(String s) {
        return s == null || s.isEmpty();
    }

    /** null か空白だけなら true */
    public static boolean isBlank(String s) {
        return s == null || s.isBlank();
    }

    /** null なら空文字にする */
    public static String nullToEmpty(String s) {
        return s == null ? "" : s;
    }

    /** 空白だけなら null にする(DB に入れる前の正規化) */
    public static String emptyToNull(String s) {
        return isBlank(s) ? null : s.strip();
    }
}

プロジェクト内に判定方法が 3 種類混在すると、境界の扱いがばらつきます。1 か所に集めて全員がそれを使うのが最も効果があります。

ライブラリを使う場合

// Apache Commons Lang3
StringUtils.isEmpty(s);         // null または ""
StringUtils.isBlank(s);         // null または空白だけ
StringUtils.isNotBlank(s);
StringUtils.defaultString(s);   // null なら ""
StringUtils.defaultIfBlank(s, "既定値");
StringUtils.trimToEmpty(s);     // null なら ""、それ以外は trim

// Spring
StringUtils.hasText(s);         // null でも空でもない(= 中身がある)なら true
ObjectUtils.isEmpty(s);

// Google Guava
Strings.isNullOrEmpty(s);
Strings.nullToEmpty(s);

同じ名前で意味が違う点に注意してください。Spring の hasText() は「中身がある」なので、Commons の isBlank() の否定にあたります。import を取り違えると条件が反転します。

コレクションと Optional

List<String> list = getList();

if (list == null || list.isEmpty()) { }

// 空のリストを返せば null チェックが要らなくなる
public List<String> getList() {
    return results != null ? results : List.of();
}

// 値がある / ない を型で表す
Optional<String> name = findName();
if (name.isPresent()) { }
name.ifPresent(System.out::println);
String v = name.orElse("名無し");
String v2 = name.filter(s -> !s.isBlank()).orElse("名無し");

// null を Optional にする
Optional.ofNullable(s).filter(x -> !x.isBlank()).ifPresent(this::save);

「値が無い」を null ではなく空コレクションや Optional で表すと、判定そのものが減ります。Optional はメソッドの戻り値に使うもので、フィールドや引数には使いません。

null と空文字を区別する場面

場面意味の違い
フォームの入力null=項目が送られていない / ""=入力欄が空
データベースNULL=未設定 / ''=空という値。検索条件が変わる
JSONnull=明示的に null / キーが無い=未指定
設定ファイル未設定なら既定値、空文字なら「無効にする」など
-- NULL は = で比較できない
SELECT * FROM users WHERE name = '';       -- 空文字の行だけ
SELECT * FROM users WHERE name IS NULL;    -- NULL の行だけ
SELECT * FROM users WHERE COALESCE(name, '') = '';   -- 両方

DB に入れる前にどちらかへ寄せておくと、検索条件が単純になります。「未入力は NULL」「空文字は保存しない」のように決めてください。

関連

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. プラットホーム
  2. 環境構築
  3. 文法
  4. API
  5. Servlet(サーブレット)
  6. JSP
  7. Applet(アプレット)
  8. デザインパターン
  9. フレームワーク
  10. ライブラリ
  11. Androidアプリケーション
  12. Project Jigsaw
  13. エラー一覧
  14. 日付の加算、減算
  15. 文字列の数字チェック
  16. 改行コードの削除
  17. 先頭と末端の文字の削除
  18. warファイルの中身を確認する方法
  19. nullもしくは空文字の判定
  20. beanの中身を確認する方法
  21. org.apache.log4j.Logger のログ出力で printStackTrace() のエラー内容を出力する方法
  22. Javaのバージョン確認方法

最近更新/作成されたページ