- - PR -
Javaプログラムでの処理の中断について
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-07-01 01:20
初めて投稿させていただきます。
仕事でJavaを触るようになって1ヶ月ほどですが、ソースコードを読むにつれ、少し疑問が 沸いてきています。恥ずかしい内容だとは思いますが、お答えいただければ幸いです。 件名にも書いていますが、Javaプログラムで処理の中断は行わないのか?というのが 質問です。ソースプログラムを見ても、初心者向けの書籍を見ても処理の中断がありません。 たとえば、擬似コードで書きますと、 メイン関数 { フラグ = DBへの接続関数; if ( フラグ != 正常 ) { ログ出力("エラー"); } フラグ = DBへのSQL発行; if ( フラグ != 正常 ) { ログ出力("エラー"); } フラグ = DB接続切断; if ( フラグ != 正常 ) { ログ出力("エラー"); } ログ出力("終了"); } となっており、最初のDBへの接続で失敗したとしても、プログラムは最後までエラーログを 出力しながら続けられる、といった具合です。エラーが出た時点で終了するのが自然で あると思っているのですが、Javaでは違うのでしょうか?System.exit というメソッドが ありますが、あまり使われないのでしょうか?(「現在実行している Java 仮想マシンを終了 します。」というAPIの説明は確かに怖い気がしますが)。 稚拙な質問ですが、よろしくお願いいたします。 | ||||||||
|
投稿日時: 2006-07-01 03:26
はじめまして、深山です。
中断とは、終了のことでいいんですよね? #中断と終了では、意味がまったくちがいますよ。発言から終了のことだと判りますが・・・ プロセスの終了なら、System.exit()でいいと思います。 JavaはJVM上で動いているのですから、プロセスの終了ならSystem.exit()でいいと思います。 メソッド処理から抜けるだけでしたらreturn文を使います。 | ||||||||
|
投稿日時: 2006-07-01 07:31
継続不可能なエラーが発生した場合は、
RuntimeException(又はその派生クラス) を throw し、 VM側に処理の終了を任せるのが普通だからでは? | ||||||||
|
投稿日時: 2006-07-01 09:52
おはようございます。
ご回答ありがとうございます、深山さん、inaさん。
はい。「終了」のことです。曖昧な言葉遣い申し訳ありません。 System.exit() でよろしいんですね。安心しました。私のイメージでは、System.exit() は、 +---------+ +---------+ |プロセス1 | |プロセス2 | +---------+ +---------+ +---------------------+ | Java VM | +---------------------+ であり、Java VM を終了するということは、関係ないプロセスまで終了してしまうのでは ないかと思っていたからです。深山さんの文から推測いたしますと、 +---------+ +---------+ |プロセス1 | |プロセス2 | +---------+ +---------+ +---------+ +---------+ | Java VM | | Java VM | +---------+ +---------+ のような感じということですね(勝手な理解かもしれませんが…)。
なるほど。RuntimeException で終了を任せる、といった方法があるんですね。勉強になります。 今回の場合、DBへの接続関数が失敗した場合、SQLException(extends Exception)が throw されるようなんですが、これは catch して、改めて自作の例外(extends RuntimeException) を throw する、というのがよい流れ、という理解でよろしいでしょうか。 ただ、今回見ているソースコードは、スケジュールで起動するバッチプログラムのようです。 ですので、特に標準エラー出力に対する出力は不要で、決められたログファイルにエラーを 吐ければよい、といった流れのようです。そういった場合、SQLException を catch した タイミングで、ログ出力し、System.exit() で抜けるのがよいのかなぁ、とも思えます。 # 変なこといってたらすみません。 「例外」は奥が深いようですので、もう少し調べて見ます。ありがとうございました。 | ||||||||
|
投稿日時: 2006-07-01 11:58
System.exitはあまりお奨めできません。
同じようにRuntime.exitやRuntime.haltもです。 設定次第でSystem.exitを許可しないようにもできますし、 キャッチした例外に対して適切な例外処理を行い、 必要に応じて呼び出し元に例外をスローするのが、 一般的な書き方になると思います。 | ||||||||
|
投稿日時: 2006-07-01 12:28
書籍で、そこまできちんと解説したものはそうそうないと思います。というか、そもそもコードの解説は、その章で着目しているクラスやメソッドの説明だけに特化したものなのでエラー処理は省いているものです。ちゃんとエラー処理まで書いてあるほうが良いのでしょうけど、そうなるとコードの量が何倍にもなってしまいます。エラー処理のための章が別になっていればそれで良いと思いますが、そういう章がなかったりすることも多いですけど。 モジュール化を意識して書くと、普通のメソッドの中で System.exit が登場することはないです。汎用のサブルーチン内で勝手に終わられる可能性があると、呼ぶ側が困ってしまいます。こういう前提で考えると System.exit を書くとすれば、main メソッド内だけにするのが良いと思います。もっともこうなると普通は return だけで済みますので、戻り値を返すためにだけ System.exit を使えば良い、ということになります。 ネストして呼ばれたサブルーチンから main に戻るまでのやりかたは、結局は戻り値や例外をいかにうまく使うか、という議論になります。 -- unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86} | ||||||||
|
投稿日時: 2006-07-01 20:32
かつのりさん、unibon さん、ご回答ありがとうございます。
なるほど、基本的には System.exit などの途中でプログラムを終わらせるのではなく、 あくまでも呼び出し元に「お知らせ」のみをして、判断してもらう、ということですね。
一番聞きたかった回答はこれだ!と思えるような回答ありがとうございます。 どう処理するのが正しいのかが分かってない状態でしたので、ようやく方針が見えて参りました。 おっしゃる通り、深い階層のメソッドからの異常信号を main まで簡潔かつスマートに 引き上げられるかがポイントになりそうです。同じ例外を main にたどり着くまで発生させ 続けるなんてナンセンスに感じますので、そのあたりをソースコードを眺めながら 研究して見たいと思います。本当にありがとうございました。これからもよろしくお願いいたします。 |
1