質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.53%

  • Java

    15539questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • 例外

    33questions

    例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外の存在理由がよくわからない

解決済

回答 8

投稿

  • 評価
  • クリップ 10
  • VIEW 7,761

Anoaji

score 40

例外について

プログラミングは例外処理がついてまわるものだと思いますが、コンパイルエラーになること以外で、なぜ例外をキャッチ・あるいは投げなければならないかが不明です。

疑問点

下のソースコードはDB接続の際の、凡庸な例外コードです。疑問が4つあります。

①例外が起こると強制終了になるが、キャッチしても同じことでは
(エラー画面にならないことがメリット?)

②の箇所に書く正しい処理はこれで正しいか?(エラー原因を突き止めるだけでいいのか。だとしたら、エラー処理が強制な理由がしっくりきません)

③この箇所にたどりつくまでにconがnullになる時はどんな時か

④よく本でfinally文で例外をキャッチしてもやることないため処理は不要ですと書いてありますが、僕にとっては他のキャッチ箇所もログを出すだけであれば、ここもprintstacktrace();を書けばいいのにと思ってしまいます。

ソースコード

//例外文のみ
 catch(SQLException e){
   e.printstacktrace();・・・・・・②
 }finally{
  if (con != null){ ・・・・③
   try{
    con.close();
  }catch(SQLException e2){
    //処理は不要・・・・・・④
 }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 8

checkベストアンサー

+14

①例外が起こると強制終了になるが、キャッチしても同じことでは? 
 (エラー画面にならないことがメリット?) 

複数スレッドで動いている場合などは影響が該当スレッドだけでおさまります

②の箇所に書く正しい処理はこれで正しいか?(エラー原因を突き止めるだけでいいのか。だとしたら、エラー処理が強制な理由がしっくりきません) 

商用で使うプログラムなどでしたらエラー原因の解析は必須です
(原因のわからないエラーは恐怖でしかありません ロジックの誤りなのかデータの異常なのか)
あと、例外が発生した場合に後続処理をさせずにソフトランディングさせる意味でもcatchは必要です

③この箇所にたどりつくまでにconがnullになる時はどんな時か 

処理本文が乗っていないので何とも言えません
conのNewに失敗したとかconをNewする前に例外が発生したとかでしょうか

④よく本でfinally文で例外をキャッチしてもやることないため処理は不要ですと書いてありますが、僕にとっては他のキャッチ箇所もログを出すだけであれば、ここもprintstacktrace();を書けばいいのにと思ってしまいます。 

この例のように処理がcloseだけならば原因はもっと前にあるからとかではないでしょうか?
別に書いても問題はないと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/25 12:11 編集

    つまり、
    ①「プログラム全体を止めたくない場合は例外が必要」ってことですね!

    >原因のわからないエラーは恐怖でしかありません
    確かにこれはその通りですね。エラー原因究明のためにキャッチは必要な気がしました。
    >ソフトランディングさせる
    つまり、キャッチした場合に、その中で処理をがっつり書くんでしょうか?あまり見たことがありませんが、、

    ③なるほどです!newが失敗の時もキャッチされ終了しますね!


    >処理がcloseだけならば原因はもっと前にあるからとかではないでしょうか?
    あまりイメージがわきません。。closeの際に例外が起こったら原因はそこなのでは、、と思ってしまいます。

    キャンセル

  • 2016/02/25 13:18

    2のソフトランディングさせるのは
    ・後続処理をさせないことで誤ったデータを登録しない
    ・データの一貫性を持たせるためDBのロールバックをさせる
    ・作業途中を示すために配置している空ファイル(またはディレクトリ)を削除する
    等がよくある話です

    closeは基本解放処理がメインになることが多いです
    解放でエラーが起こるのは大抵確保に失敗しているためです
    確保でエラーメッセージを出しているので解放でエラー出す出さないは方針によると思います
    (開放する配列要素の数で判定に誤りがある場合もあるのでログを出させるのはありだと思います)
    あとcloseに失敗するとそれ以上終了のためにできる手段がないというのもありますね

    キャンセル

  • 2016/02/27 15:44

    >データの一貫性を持たせるためDBのロールバックをさせる

    >確保でエラーメッセージを出しているので解放でエラー出す出さないは方針によると思います

    この辺が実体験もあり、相当イメージが湧きました。kutsulogさんのような詳しいエンジニアが近くにいたらどれだけ苦労しないか、、と思いました。
    >あとcloseに失敗するとそれ以上終了のためにできる手段がないというのもありますね
    ちなみに「接続のクローズに失敗」した場合、**再度クローズさせる**ってことをすればいいのに、、と素人目で思ってしまいます。ただそれだとネストが永久に深くなってしまいそうですね。詳しくありがとうございます。

    キャンセル

+11

Javaはキャッチを強制される「検査例外」があるので事情が違いますが、他の言語では例外を投げっぱなしにしても特に問題ありません。キャッチされない例外が起きれば、確実にそこで終了してくれます。もし何かしらの対策を行うのであれば、キャッチして続けることも可能です。

例外のないC言語では、返り値やグローバル変数で異常事態を通知していましたが、これらは呼び出す側で参照しなければただ無視されてしまいます。例外の場合は、「何もしなければエラーで落ちる」ということで、より安全になっています。

なお、4のように「例外をキャッチした上で無視する」ことも可能です。ふつうはよろしくない形ですが、ここの場合は「接続のクローズに失敗」したところで、「できることもなければ何かをする必要もない」ということで、ただ無視させています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/25 12:22 編集

    >確実にそこで終了してくれます。もし何かしらの対策を行うのであれば、キャッチして続けることも可能です。

    強制終了でも問題ないと思っていたので、例外の必要性が不明でしたが、後続処理が必要な時に、例外が必要なんですね。後続必要ないならログ確認のためって感じでしょうか。

    ちなみに「接続のクローズに失敗」した場合、**再度クローズさせる**ってことをすればいいのに、、と素人目で思ってしまいます。

    キャンセル

+6

コンパイルエラーと例外は発生するタイミングが異なるので比較にはならないです。
また、エラー処理をするか、例外で扱うかは宗教論争的な面もありますので、開発しているプロジェクトのルールに従えば良いと思いますが、想定される問題はエラーで、動作時に想定されない問題を例外で扱うと個人的には考えています。

基本的にAシステムとBシステムはどちらも強調して動作する、両方が動いていないことはないという前提のシステムにおいて、AシステムからBシステムが動いているかを毎回チェックして、Bシステムが動作していないので、動かしてくださいというメッセージを利用者に提示する必要はなく、運用者に迅速に伝えることの方が必要です。
そのような場合に例外を使うとかでしょうか。

また、開発時には例外画面を出して、スタックトレースを出した方が問題解決に直結するという意味ではおっしゃる通りと思いますが、本番の際に、問題が発生した場合にどこまで何をすべきかというのは、上に書いたようにプロジェクトの方針に依存するのではないかと思います。
最近はクラッシュレポートのためのライブラリもありますので、適宜利用すれば良いかと。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/25 12:17

    >AシステムからBシステムが動いているかを毎回チェックして、
    >Bシステムが動作していないので、動かしてくださいという
    >メッセージを利用者に提示する必要はなく、運用者に迅速に
    >伝えることの方が必要です。
    エラー処理にしない理由は非常に納得です。また、強制終了でない理由としては、例外書かないと、運用者に自動で伝わらないためタイムロスがもったいないってことでしょうか?

    キャンセル

  • 2016/02/25 13:12

    タイムロスが勿体無いか否かはそのシステムを利用したサービス価値により決まるものですが、例示したシステムにとってはそのようにすべきという意図です。

    キャンセル

+5

(1) についてですが、

// For文
for (int i = 0; i < storeList.size(); i++) {
    try {
        // 一店舗ごとに処理します
    } catch(Exception e) {
        // もし仮にA店でコケても、続けてB店を処理したいのでcatchする
    }
}


みたいな使い方とかします。

あとは

「CSVファイルを読み込んでDBに取り込む。
処理後、CSVファイルは
成功した場合はokフォルダへ、失敗した場合はngフォルダへ移動する」

みたいな処理の場合、もしDB更新に失敗しても
そのあとの「ngフォルダへのファイル移動」処理を実行しないといけないので
そういう場合もキャッチしたりしますね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/25 11:57

    確かに続けて処理を行ないたい場合は、例外キャッチしたほうがいいですね。勉強になります。

    キャンセル

+2

ここなどわかりやすく書かれています。参考になれば幸いです。

http://www.atmarkit.co.jp/ait/articles/1111/01/news131.html

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/27 15:33

    わざわざリンク探していただいてありがとうございました。これまで見た中でもかなりわかりやすかったです。

    キャンセル

+2

例えばDBをあれこれするライブラリがあって、
DBへの接続に失敗した場合にどうするかは、
ライブラリ作成側が決めることではなく、
利用側が決めることです。

再接続したい場合もあるでしょう。
何が起こったかログ書いて後は異常終了でいい場合も有るでしょう。
何もしないでいいやと言う場合もあるでしょう。
とにかく、非常事態に何をするかは自由に決めたいわけです。

このように、何か異常があったとき、何をするかを利用側に決めさせる仕組みの一つが
よくある例外機構です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/26 22:17

    なるほど。javaは検査例外に関しては強制だから、なぜ?と思ってしまいましたが、状況によって対応を変化できるための仕組みとして存在してると考えたほうがよさそうですね

    キャンセル

+1

例外処理機構は、とても大事な問題を含んでいます。
回答になりませんが、参考になるページを幾つか紹介します。

... 
プログラムの実行中に例外的な状況になってプログラムの実行順番を変えたい場合が在ります。
しかし、例外が起きる可能性のあるところに、いちいち条件分岐のプログラムを書くと、プログラムの流れがとても解りにくくなります。
めったに使われることの無い、プログラムの本流ではない処理が頻繁にプログラムの中に出てくると、本来の流れが把握できなくなるのです。
さらに、例外に対応するには関数呼び出しを遡って処理する必要が出てきたりしますから大変です。
C言語のプログラムであれば、例外が起きるところでは例外の有無をチェックして処理部へgoto文で跳ぶ形のプログラムを書くことになるでしょう。
しかしgotoでは自由度が在りすぎて例外処理のパターンが定まりません。
そこで、java言語やC++言語には例外処理の手順が構文として用意されています。
...

...
例外
近年では、エラーが発生した際は例外メカニズムで処理すべきという認識を大方の人が持っているようです。
少なくともエラーコードを返す方法が最適でないことについては誰も異論はないでしょう(私もありません)。
エラーコードを介した処理よりもっと豊かで、実用性と堅牢性を兼ね備えたものが必要ですよね。

例外の問題は、このメカニズムが実際はgoto文をベースにしたものだということです。
先ほど、goto文は害悪であると学んだばかりですよね。
...

...
我々は、処理構造を制御するためのtry-catch-finally形式の例外処理機構によって、コードが入り組んでしまうと考えています。
しかも、ファイルを開けないといった、ごく一般的なエラーをさも特別なエラーであるかのように扱わせる傾向があります。
Go言語では、異なるアプローチを取りました。
Go言語では戻り値として複数の値が返せるので、一般的なエラーハンドリングの場合、戻り値といっしょにエラー情報を返すことができます。
>エラー型は標準化されており、Goの他の機能と相まってエラーハンドリングがすっきりしたものとなります。
これは、他の言語と大きく異なる点です。
...

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

.netでの話ですが、とある人はブレークポイントを設定する為だけにCatchを書いていました。当然Catchの中身はthrowのみ。開発中ならいざ知らずリリース版にまで残す処理じゃないよね・・・

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Java

    15539questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • 例外

    33questions

    例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。