55
45

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Javaで三項演算子はどこまで許されるか

Last updated at Posted at 2018-02-26

はじめに

この記事ではJavaに限った話をします。

先日、以下の記事を書きました(タイトル変更してます)。

この記事で、以下のように三項演算子を良い例として挙げました。

String userType = isAdmin ? "管理者" : "一般";

しかし、三項演算子は読みにくいという反応が結構ありました。あくまでシンプルな例として挙げたつもりだったのですが、説明不足だったので、別途記事を書きます。

三項演算子を使っていいのは、単純なもののみに限られるのが自分の中での結論です。

三項演算子とは

三項演算子(ternary operator)は以下のような形をしています。

<条件式> ? <trueのときの値> : <falseのときの値>

どの書き方ならよいかの話をする前に、自分が「どこまでならよい」と感じているのか、その例を書きます。

/*
 * 白(ほぼ問題なし)
 */
String userType = isAdmin ? "管理者" : "一般";

String userType = user.isAdmin() ? "管理者" : "一般";

UserType userType = user.isAdmin() ? UserType.ADMIN : UserType.NORMAL;

String userName = user.isAdmin() ? "管理者" : user.getName();

/*
 * 白に近いグレー
 */
return user.getType() == UserType.GUEST ? "ゲストユーザ" : user.getName();

/*
 * 黒に近いグレー
 */
String userName = user.getType() == UserType.GUEST ? "ゲストユーザ" : user.getName();

/*
 * 黒(アウト)
 */
String userName = user.getType() == UserType.GUEST ? "ゲスト" : user.getType() == UserType.ADMIN ? "管理者" : user.getName() + "さん";

何が基準か

三項演算子の定義に戻ります。

<条件式> ? <trueのときの値> : <falseのときの値>

先程の例で、どのようなパターンが良いのか、悪いのかは、以下のように分類できます。

  • 白(ほぼ問題なし)
    • 条件式
      • boolean変数
      • booleanを返すメソッド
    • true/falseのときの値
      • 定数
      • enum
      • getterなど単純な呼び出し
  • グレー
    • 条件式に ==!= での比較が入る
  • 黒(アウト)
    • ネストしている
    • true/falseのときの値が、単純な呼び出し以外

三項演算子が嫌われがちなのは、どこまでが条件式なのか、どこまでがtrueのときの値なのか、頭の中で字句解析、文法解析するコストが高いからです。また、 ==!= での比較が入るとよくないのは、代入の = と見間違えて、一瞬混乱するからです。

なので、単純な書き方以外は避けるようにしています。

どのように書くべきか

以下のように書くこともできますが、後ろ向きな解決案なので、自分は好きではありません。

String userName; // ここでの初期化は無駄なのでしない

if (user.getType() == UserType.GUEST) {
    userName = "ゲスト";
} else if (user.userType() == UserType.ADMIN) {
    userName = "管理者";
} else {
    userName = user.getName() + "さん";
}

自分なら以下のように、メソッドを作ります。この場合はUserクラスのメソッドとして実装できますが。

なお、今回は元の条件式と合わせるためにif文にしましたが、enumの場合はswitch文を使うことが多いです。

private String getName(User user) {
    if (user.getType() = UserType.GUEST) {
        return "ゲスト";
    } else if (user.getType() == UserType.ADMIN) {
        return "管理者";
    } else {
        return user.getName() + "さん";
    }
}

// 呼び出し元
String userName = getName(user);

おわりに

自分が思っていたより、読みにくくなるパターンのほうが多かったです。三項演算子を禁止するのはやりすぎだと思いますが、単純なもの以外は使わないくらいでいいと思います。

55
45
9

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55
45

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?