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月当時、記事を修正しました。