Try-Catch内ですべてのステートメントを記述する必要があるのはなぜですか?


12

私の会社長は、すべてのコード、つまりTry-catchステートメント内のすべてのコードを記述する必要があると言います。ここで、「申し訳ありませんが安全です」というアプローチはここで理解できますが、ラベルが作成され、フォームの位置が設定されたときに例外があると考えるのはあまりにも簡単ではありません。このような単純な操作で例外が発生する場合があります。


4
これは、パフォーマンスを向上させるためにすべての SQLをストアドプロシージャとして作成する必要があると言っている同じ人々によるバズ用語のように聞こえます。
スポンジ

5
「コードで実行時エラーが発生した場合、解雇されます。」チキンのゲームは、対戦相手がハンドルを投げ、ブレーキペダルを窓の外に出すまで見るのは楽しいです。
ジェフ

4
@Jeff O-ソフトウェア開発において、相手は貨物列車だと実際に信じています。
ジョリスティマーマンズ

5
このスタイルの例外処理で私が聞いた最高の表現は、「死体を直立位置に釘付けする」ことです。つまり、アプリケーションが予期しない状態のままになります。Fail Fast、Fail Loudlyははるかに現代的なアプローチであるため、実際にすべてのバグを解決できます。
ブルック

2
リクエストの主題は無関係です...「私の会社長がコーディングするべきだと言っている...」と言うだけで大きな赤旗です。それは微細管理です...これは彼の仕事ではありません。
ジョエルファン

回答:


14

私の会社長は、すべて、つまりTry-catchステートメント内のすべてのコードを記述する必要があると言います。

まあ、これは少しやり過ぎで、ノイズの多いコードになります。try catchハンドラーですべてのコード(各メソッドなど)を作成することの利点は何ですか?ほとんどの場合、修正すべきエラーがあることを伝えるだけです。多くの場合、そもそも例外は回避できますし、回避すべきです。

フォールトメソッドがcatch自体を実行しない場合でも、スタックトレースを調べるだけでコードの原因を明らかにできます。開発者が例外でスタックトレースを破損する場合がありますが、多くの例外ハンドラを使用している場合ははるかに多くの場合です。何でもそうです:少しでも良いですが、あまりにも多くは毒です。

例外処理は確かに非常に簡単です。

例外をキャッチ

  • 例外への反応として特別なアクションが必要なときはいつでも
  • 例外が処理されない場合、プログラムが一貫性のない状態のままになるたびに

考えてみると、ほとんどの場合、発生する例外を処理するのに適した場所は1つだけです。したがって、ハンドラーはその場所にある必要があります。

多くの例外はそもそもスローされるべきではないので、例外処理を中心に制御構造を構築せず、いつでもどこでも可能な例外の発生を避けるようにしてください。

物事が(修復不可能に)間違った場合は、早期にクラッシュすることを忘れないでください。すべてのコードをtry-catchステートメントに入れるのは馬鹿げていますが、すべての例外を報告して記録することを忘れないでください。


+1これはノイズの多いコードにつながるだけでなく、パフォーマンスがさらに低下します。tryブロックにステートメントを配置すると、HotSpotコンパイラは、そうでなければ最適化を適用できなくなります。
オリバーワイラー

@Oliver Weiler:HotSpotコンパイラーがtry / catchブロックで実行しない最適化を説明する引用はありますか?
カイプロII

16

しかし、ラベルが作成され、フォームの位置が設定されたときに例外があると考えるのはあまりにも簡単ではありません。このような単純な操作で例外が発生する場合があります。

はいぜったいに!あなたが予見しなかった事がうまくいかない方法が常にあります。また、「チキンハート」は、このコンテキストで使用するばかげた表現です。ソフトウェア開発は、潜在的な問題を無視してmachismoを証明することではありません。

有効な質問と、コーディング標準で必要とされている時点で例外をキャッチすることが有用かどうかです。あなたのステートメントは、すべてのメソッド本体の周りにtry / catchブロックを持たなければならないように見えますが、例外で有用なことをすぐに行うことができないことが多いため、それは本当にばかげています。適切な時点で処理されるコールスタックを伝播します。


13
私のアプリは、例外をスローするよりもよく知っているか、彼らは彼らの人生の暴行を取得します。彼らはあなたがチキンハートだと思うと、彼らはあなたの周りにクラッシュします。
ジェフ

@Michael Borgwardt:ふふ、だからあなたは私に投票した。あなたはこの質問に反対票を投じましたが、唯一の反対票は私の投稿にあります。自我や自尊心に深刻な問題があるようです。他の質問にも気づきました。他のプログラマーにも良い答えがあります。
ファルコン

@Falcon:私はこの質問について何も採決しませんでした。どうしてあなたがそうでないと信じるようになるのか分かりませんが、誰かが深刻な自我の問題を抱えているなら、それはあなたです。
マイケルボルグ

@Michael Borwardt:たぶん私は間違っています。その場合、私は謝罪します。それはあなたがここであなたが投票したと私に思わせたのはあなた自身の質問に対するちょうど投票であるかもしれません。ごめんなさい。
ファルコン

8

私はこれを逆に回します。はい、一般的なルールとして、例外処理は良いことですが、実際には、キャッチされた時点で考えられるすべての例外を賢明な方法で処理できますか?時々、特にミッションクリティカルなソフトウェアを書いていない場合は、物事が恐ろしく悪くなったときに、途中で制御された方法で単にクラッシュして焼いた方良いでしょう。

キャッチされる可能性のあるすべての例外を処理できることを100%確信できない場合は、何らかの一般的な例外ハンドラーを作成して、プログラムのメインループをラップすることをお勧めします。あなたが作業しているどのような言語に依存あり、することができますように例外に関する多くの詳細としてログオンし、プログラム状態(どこかに保存します。のデータは、ユーザーが現在不利に働いている保存何よりも-覚えて、それがすべてのこの時点では壊れている可能性があります)、 等々。次に、例外を再スローし、OSに適切に処理します。このキャッチオール例外ハンドラでは、壊滅的な障害に備えてください。次に、プログラムを再起動したときに、この状態が何らかの意味で有用かどうかを確認し、有効であれば復旧できるものを復元します。バグ報告をあなたに送り返すようにユーザーに提案することもできます。


5
+1:すぐに正しく対処できない場合は、例外をキャッチしないでください。(残念ながら、時にはあなたが持っているトラップし、それはちょうどそれが再び自由に歩き回るが、APIの強制変換の一環として、異なるタイプとしてタグ付けできるようにする:。私はそれを嫌い)
ドナル・フェローズ

6

catchブロックはリソースの点から見て非常に高価なので、全体的にtry / catchの使用は推奨されません。Try / catchの使用は、リスク管理を思い出させます。リスク管理には2つの側面があります。

  1. リスク発生の確率
  2. 受けるダメージ

さて、家を出ると、どこかで頭にピアノが落ちますが、起こりそうにないかもしれませんが(0.001%)、あなたを殺すことができます。

例外処理はそのようなものです。試行ブロックは高価ではありません。しかし、キャッチブロックは、スタックトレースのテーブルを作成する必要があるため、非常に高価です。したがって、try / catchブロックに関する決定を行う際には、catchブロックにヒットする可能性がある回数を考慮する必要があります。10,000回の使用のうち、1回だけヒットしてから使用します。しかし、それがフォームであり、ユーザーがおそらく50%回正しく入力しない場合は、そこでtry / catchブロックを実行しないでください。

例外が発生する可能性が高い場所では、例外の発生if {} else {}を避けるためにブロックを使用することをお勧めします。たとえば、次のように書く代わりに、2つの数値を除算する場合:

try
{
    int result = a/b;
}
catch (DivisionByZeroException ex)
{
    // Showing a message here, and logging of course.
}

あなたは書くべきです:

if (b == 0)
{
    int result = a/b;
}
else
{
    // Showing a message to user to change the value of b, etc.
}

2
基本的には単なるアプリケーションロジックである「例外」を処理するためにif / elseを使用するための+1。
モーガンハーロッカー

ユーザー関連の場合は、コンピューターは人間よりもはるかに高速であることを忘れないでください。フォーム送信の50%でスローされる例外は、多くのユーザーであっても1秒に数回しか発生しない可能性があります。
ドナルドフェローズ

1
try / catchブロックの回避については同意しません。常に例外を予測しようとすると、エラーが発生しやすく、開発者の時間がかかり、コードが読みにくくなります。100万の例外をスローしキャッチするループは、マシンで実行するのに500ミリ秒かかります(空のループの場合は1ミリ秒です)。パフォーマンスのペナルティが重要であることがわかっている場合を除き、例外を使用する必要があります。例外はコードの信頼性を高め、前のコードが正常に実行されたと想定できるためです。
カイプロII

@ cosmic.osmo、スタックトレースを取得しますか、それともキャッチしますか?

3

必要に応じてtry-catchを使用する必要がありますが、すべての例外をキャッチせず、ログも記録しないでください。その時点では、コードのにおいと見苦しい作業です。


1
ロギング用に+1。野生のプログラムはブラックボックスです。それらが失敗すると、「ここに何が起こったのか」というログが問題を解決するのに非常に長い道のりをたどります。報告されなかったプログラムにエラーがあり、ログでそれらを見つけた後にのみ発見されました。
アンドリューニーリー

2

私は個人的に例外に耐えることができません、それらは非常に、非常に、非常に正しく処理するのが非常に難しいです。そして、破損したデータを破損させないようにすることは、非常に困難です。

http://blogs.msdn.com/b/mgrier/archive/2004/02/18/75324.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx

http://www.joelonsoftware.com/items/2003/10/13.html

次のようなすべての関数を呼び出さない場合:

try
{
    TrivialFunction();
}
catch(TypeAException)
{
    //MaybeFix
}
catch(TypeBException)
{
    //MaybeFix
}
catch(TypeCException)
{
    //NO FIX - CORRUPT DATA
}
catch(TypeDException)
{
    //NO FIX - UNKNOWN STATE
}
catch(OutOfMemoryException)
{
    //Try to fix this one! Destructors might allocate on their own ;)
}
catch(Exception)
{
    //Nothing to see here, move on, everything is OK ;)
}

すべての出口点で正しくクリーンアップする方法はありません。例外は厳しいです!

例外の唯一の良い点は、それらをキャッチしないと、予期しない動作でアプリがクラッシュすることです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.