条件分岐・Javaソースコードの書き方

if文に指定する条件

if文に指定する条件は、通常、ユーザの操作によって生み出された情報です。ユーザの操作によって生み出された情報には、次のような事があると思います。クリック操作

  • ユーザのマウス操作によって、生み出された情報。
    例:
    マウスをクリックした、という情報(クリックイベント)
    マウスを動かした、という情報(マウス移動イベント)
    など。
  • キーボード操作によって、生み出された情報。
    例:
    aキーなど、キーボードが押下された、という情報(キー押下イベント)
    a文字など、キーボードから入力された文字
    など。

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

このように 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”文字列は、ユーザが「メッセージの件名」リンク項目をクリックしたことが「きっかけ」で、作成された文字列です。

「その他の場合」の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変数に設定されている
という自作のエラーが出力されます。このエラー情報より、Javaソースの中から「この不具合の原因部分」を探しやすいでしょう。

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

絶対に実行されない文

例えば「その他の場合のif文」のように、プログラムの仕様上、絶対に処理が来ない場所があります。
もしもプログラム記述ミスなどの理由で、その場所に処理が来た場合、

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

と、良いです。プログラムの不具合を修正する際に、役立つからです。
絶対に処理が来ない場所では、catch文で対処しなくて良い例外――例:RuntimeExceptionクラス――を通知する、と良いです。

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

この場合、処理の続行を中止して、開発者に対して、プログラムが異常な処理手順を実行したことを伝えると良いです。例外を通知すると、ログなどに記録されます。ログによって、プログラム異常が開発者に伝わると思います。

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

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

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

また、RuntimeExceptionクラスに対しては、次のような考え方もあるそうです。
ある不具合が起きたことを例外で示したが、その例外をキャッチして処理しても、プログラムを頑健にすることに「役立たない感じ」がする。
そんな場合では、プログラムを頑健にするのに役立たないcatch文を、書きたくない。その意志を示す場合に、RuntimeExceptionクラスを利用する。
このような考え方もあるようです。

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

エラー以前、自作のJavaソースコードで、絶対に実行されない部分に処理が来た場合、Errorクラスを通知していたことがありました。
その当時、「例外クラスの使い分け」を、あまり意識していなかったからです。Errorのほうが、RuntimeExceptionよりも文字数が短かったから、使っていました。

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

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

コンピューター
この記事をシェアする

グッズ・メモランダム