ユーザー操作によって発生した情報、Javaプログラミングの条件分岐

Javaプログラミングのif文に指定する条件は、どんな情報でしょう?

Javaプログラミングのif文に指定する条件は、一般的に、ユーザー操作によって発生した情報です。
例えば、マウスをクリックしたという情報があります。

Javaプログラミングでif文を書くことは、ユーザー操作に対応した処理を実行させることになります。

ユーザー操作によって発生した情報、Javaプログラミングのif文に指定する条件

if文に指定する条件は、通常、ユーザー操作によって発生した情報です。

ユーザー操作によって生み出された情報には、次のようなものがあります。

ユーザーのマウス操作によって、生み出された情報

例:

  • マウスをクリックした、という情報(クリックイベント)。
  • マウスを動かした、という情報(マウス移動イベント)。

キーボード操作によって、生み出された情報

例:

  • aキーなど、キーボードが押下された、という情報(キー押下イベント)。
  • a文字など、キーボードから入力された文字。

※近年では、ユーザーがディスプレイ画面をタッチした、という情報(例えばタッチイベント)もあります(2017年当時)。

プログラム実行時に作成された情報、if文に指定する条件

このようにif文に指定する条件は、プログラム実行時に作成された情報です。

if文に指定する条件として、プログラム記述当時に(コンパイル時に)発生している情報を指定することは、あんまりないと思います。

Javaプログラミングでif文を書くことは、プログラム実行時のユーザー操作に対応した処理を実行させることになります。

if文の条件に、「ユーザー操作によって発生した情報」を指定する例

以下、if文の条件に「ユーザー操作によって発生した情報」を指定している例を、書きます。
なお、プログラムの詳細を理解する必要は、ありません。

public ActionForward perform(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){
    ...
    MessageBoardForm boardForm = (MessageBoardForm)form;
    String action = boardForm.getAction();
    if (action.equals("forward")){
        int boardID = boardForm.getBoardID();
        ...
    }
    else if (action.equals("back")){
        int boardID = boardForm.getBoardID();
        ...
    }
    else if (action.equals("write")){
        return mapping.findForward("contributionDo");
    }
    else if (action.equals("message")){
        int boardID = boardForm.getBoardID();
        ...
    }
    else{
        //next 休止中.htmlなど、表示する。
        throw new RuntimeException("invalid action=" + action);
    }
    ...
}

if文の水色の部分action.equals("forward")などが、ユーザ操作によって生み出された情報を指定している部分です。

例えば"forward"という文字列は、ブラウザに表示されているWebページにて、ユーザがマウスで「進む」リンク項目をクリックしたことが「きっかけ」で、作成された文字列です。

上記の例は、if文の条件に、ユーザのマウスクリック操作が「きっかけ」で作成された文字列を、指定しています。
よって適切に、if文を使用している例と言えます。

そして、action.equals("back")の"back"文字列は、ユーザがマウスで「戻る」リンク項目をクリックしたことが「きっかけ」で、作成された文字列です。

同様に"write"文字列は、ユーザが「投稿する」リンク項目をクリックしたことが「きっかけ」で、作成された文字列です。

"message"文字列は、ユーザが「メッセージの件名」リンク項目をクリックしたことが「きっかけ」で、作成された文字列です。

Javaプログラミングのif文
Javaプログラミングのif文・イメージ画像

Javaプログラミング、プログラムで実行されない「その他の場合」のif文

if文で処理を分ける場合、「その他の場合」においてログ情報を出力しておくと、デバッグ時に役立ちます。

プログラム処理上(プログラム仕様上)実行されない「その他の場合」は、当然実行されないので、プログラム処理を書く必要はありません。

しかしプログラム記述ミスや、プログラム作成時に予想できない不具合によって、実行されない「その他の場合」の部分に、プログラム処理が来てしまうことがあります。

その場合、プログラムが期待通りに動作しない可能性があります。

そのような時、「その他の場合」においてログ情報を出力しておくと、プログラムの不具合に気づく「きっかけ」になる、と思います。

「その他の場合」のif文の例

以下に、「その他の場合」のif文について、ログ情報を出力している例を示します。
プログラムの詳細を理解する必要は、ありません。

public ActionForward perform(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){
    ...
    MessageBoardForm boardForm = (MessageBoardForm)form;
    String action = boardForm.getAction();
    if (action.equals("forward")){
        int boardID = boardForm.getBoardID();
        ...
    }
    else if (action.equals("back")){
        int boardID = boardForm.getBoardID();
        ...
    }
    else if (action.equals("write")){
        return mapping.findForward("contributionDo");
    }
    else if (action.equals("message")){
        int boardID = boardForm.getBoardID();
        ...
    }
    else{
        //next 休止中.htmlなど、表示する。
        throw new RuntimeException("invalid action=" + action);
    }
    ...
}

if文の「最後のelse部分」が、「その他の場合」の処理です。

次の文で、ログ情報を出力しています。

throw new RuntimeException("invalid action=" + action);

action変数の文字列で処理を分けていますが、どの場合にも当てはまらない時に、ここに来ます。

上記のプログラムでは、プログラム仕様上ありえない場合に――action変数に「無効な文字列」が設定された場合に――処理が「その他の場合」に来ます。

処理が「その他の場合」に来る時は、プログラム処理上、不具合が起きています。
よってRuntimeExceptionクラスを作成して、実行時に解決できないエラーが発生した、ということで処理を中断しています。

この自作のエラーは、ログファイルに記録されます。
よってプログラム処理で、何か不具合が起きていることに気がつけます。

処理が「その他の場合」に来た時、考えられるプログラムの不具合

処理が「その他の場合」に来た時、プログラムの不具合として、次の事が考えられます。

例:プログラムの記述ミス

  • action変数に設定する文字列を、間違って記述してしまった。
  • action変数の分岐処理(例:else ifブロック)を、書き忘れてしまった。

ここで上記のプログラム例において、次の場合を考えます。

  • acton変数に、メッセージの削除を示す"delete"文字列が設定されていた。

この時、ユーザーがメッセージの削除命令を実行しても「メッセージが削除されない」という不具合が起きます。

なぜなら、メッセージの削除を示す"delete"に対する「else ifのブロック」が、書かれていないからです。

しかしログファイルには、
無効な文字列"delete"が、action変数に設定されている
という自作のエラーが出力されます。

このエラー情報により、ソースコードの中から「この不具合の原因部分」を探しやすいです。

※ここまでの記事は、2003年6月当時の記事になります。

Javaプログラミング、絶対に実行されない文

例えば「その他の場合のif文」のように、プログラムの仕様上、絶対に処理が来ない場所があります。

もしもプログラム記述ミスなどの理由で、その場所に処理が来た場合、

  • プログラム処理を中止する、
  • プログラム開発者に、プログラム処理が「この場所に来たこと」を伝える

と、良いです。

プログラムの不具合を修正する際に、役立つからです。

絶対に処理が来ない場所では、

catch文で対処しなくて良い例外、
例えばRuntimeExceptionクラスを通知する、

と良いです。

プログラムの仕様上、絶対に処理が来ない場所に処理が来た場合、プログラムが「異常な動作をする可能性」があります。
なぜなら、プログラム仕様外の処理手順が実行されているからです。

この場合、処理の続行を中止して、開発者に対して、プログラムが異常な処理手順を実行したことを伝えると良いです。

例外を通知すると、ログなどに記録されます。ログによって、プログラム異常が開発者に伝わると思います。

catch文で処理しなくて良い例外クラス

ErrorクラスとRuntimeExceptionクラスは、catch文で処理する必要がない例外クラスです。
これら例外クラスの使い分けについて、次のような意見があります。参考に書きます。

  • Errorクラス
    実行環境(JavaVMなど)の内部で発生した致命的なエラーを、示します。
    プログラムから明示的に通知することはない、という考え方があります。
  • RuntimeExceptionクラス
    エラー発生の責任がプログラム開発者側にあることを、示します。
    例:プログラムの記述ミス

また、RuntimeExceptionクラスに対しては、次のような考え方もあるそうです。

ある不具合が起きたことを例外で示したが、その例外をキャッチして処理しても、プログラムを頑健にすることに「役立たない感じ」がする。

そんな場合では、プログラムを頑健にするのに役立たないcatch文を、書きたくない。
その意志を示す場合に、RuntimeExceptionクラスを利用する。

このような考え方もあるようです。

失敗談:使い分けせずに、Errorクラスを使用してしまった

エラー

以前、自作のJavaソースコードで、絶対に実行されない部分に処理が来た場合、Errorクラスを通知していたことがありました。

その当時、「例外クラスの使い分け」を、あまり意識していなかったからです。
Errorのほうが、RuntimeExceptionよりも文字数が短かったから、使っていました。

特に深く考えずにErrorクラスを使っていたので、他のプログラマーに対して「わかりにくいソースコード」になっていた、と思いました。

※2004年6月当時、記事を修正しました。

【まとめ記事】Javaアプリの品質を保つため、Javaソースコードを書くための工夫

Javaソースコードを正しく書くための、ちょっとした工夫について、ご紹介しています。 変数の寿命を限定する書き方。 肯定的な条件を優先して条件分岐する書き方。 クラス…