チェック済み例外とチェックなし例外を選択する場合
-
09-06-2019 - |
質問
Java (またはチェック例外を備えたその他の言語) では、独自の例外クラスを作成するときに、それをチェックするかチェック解除するかをどのように決定しますか?
私の直感では、呼び出し元が何らかの生産的な方法で回復できる可能性がある場合にはチェック済み例外が呼び出され、回復不可能な場合には非チェック例外がより適していると思いますが、他の人の考えに興味があります。
解決
チェック例外は、いつ使用する必要があるかを理解している限り、優れたものです。Java コア API は、SQLException (場合によっては IOException) に対してこれらのルールに従っていないため、非常にひどいものになります。
チェックされた例外 に使用する必要があります 予測可能な, 、 しかし 防ぐことができない エラー ~から回復するのが合理的.
未チェックの例外 他のすべてに使用する必要があります。
ほとんどの人がこの意味を誤解しているので、詳しく説明します。
- 予測可能だが予防不可能:呼び出し元は入力パラメータを検証するためにできる限りのことを行いましたが、制御不能な何らかの条件により操作が失敗しました。たとえば、ファイルを読み取ろうとしましたが、ファイルが存在するかどうかを確認してから読み取り操作が開始されるまでの間に、誰かがそのファイルを削除したとします。チェック例外を宣言すると、呼び出し元にこの失敗を予期するように指示することになります。
- ~から回復するのが合理的:呼び出し元に、回復できない例外を予期するように指示しても意味がありません。ユーザーが存在しないファイルから読み取ろうとした場合、呼び出し元は新しいファイル名の入力を求めることができます。一方、プログラミングのバグ (無効なメソッド引数またはバグのあるメソッド実装) が原因でメソッドが失敗した場合、アプリケーションは実行中に問題を解決するためにできることは何もありません。できる限りのことは、問題を記録し、開発者が後で修正するのを待つことです。
スローしている例外が満たされない限り 全て 上記の条件の場合は、未チェック例外を使用する必要があります。
あらゆるレベルで再評価する:場合によっては、チェック例外をキャッチするメソッドがエラーを処理するのに適切な場所ではないことがあります。その場合、自分の発信者にとって何が合理的であるかを検討してください。例外が予測可能、防止不可能で、回復するのが妥当な場合は、チェック例外を自分でスローする必要があります。そうでない場合は、例外を未チェック例外でラップする必要があります。このルールに従うと、どの層にいるかに応じて、チェック済み例外をチェックなし例外に変換したり、その逆に変換したりすることになります。
チェックされた例外とチェックされていない例外の両方について、 適切な抽象レベルを使用する. 。たとえば、2 つの異なる実装 (データベースとファイルシステム) を持つコード リポジトリは、スローすることによって実装固有の詳細が公開されることを避ける必要があります。 SQLException
または IOException
. 。代わりに、すべての実装にまたがる抽象化で例外をラップする必要があります (例: RepositoryException
).
他のヒント
から Java学習者:
例外が発生した場合、例外をキャッチして処理するか、メソッドがその例外をスローすることを宣言することでそれを処理できないことをコンパイラに伝える必要があります。また、例外が処理できない場合にスローすることを宣言することを選択する場合があります)。
コンパイラは、2つのことのいずれかを実行したことを確認します(キャッチ、または宣言します)。したがって、これらはチェックされた例外と呼ばれます。ただし、エラー、およびランタイムの例外は、コンパイラによってチェックされません(キャッチまたは宣言することを選択できますが、必須ではありません)。したがって、これら2つは未チェックの例外と呼ばれます。
エラーは、システムのクラッシュなど、アプリケーションの外側で発生する条件を表すために使用されます。通常、ランタイムの例外は、アプリケーションロジックの障害によって発生します。これらの状況では何もできません。ランタイムの例外が発生した場合、プログラムコードを書き直す必要があります。したがって、これらはコンパイラによってチェックされません。これらのランタイムの例外は、開発とテスト期間で明らかになります。次に、これらのエラーを削除するには、コードをリファクタリングする必要があります。
多くの層を備えた十分に大規模なシステムでは、チェック例外は役に立ちません。とにかく、例外の処理方法を処理するアーキテクチャ レベルの戦略が必要であるためです (フォールト バリアを使用します)。
チェック例外を使用すると、エラー処理状態が細かく管理され、大規模なシステムでは耐えられなくなります。
ほとんどの場合、API の呼び出し元がどの層にあるのかがわからないため、エラーが「回復可能」かどうかはわかりません。
整数の文字列表現を Int に変換する StringToInt API を作成するとします。API が「foo」文字列で呼び出された場合、チェック例外をスローする必要がありますか?回収可能ですか?わかりません。なぜなら、彼の層では StringToInt API の呼び出し元がすでに入力を検証している可能性があり、この例外がスローされた場合、それはバグまたはデータ破損のいずれかであり、この層では回復できないからです。
この場合、API の呼び出し元は例外をキャッチしたくありません。彼は例外を「バブル」させたいだけなのです。チェック例外を選択した場合、この呼び出し元には、人為的に例外を再スローするためだけに無駄な catch ブロックが大量に存在することになります。
何が回復可能かは、ほとんどの場合、API の作成者ではなく、API の呼び出し元に依存します。例外をキャッチするか無視するかを選択できるのは非チェック例外のみであるため、API ではチェック例外を使用しないでください。
あなたは正しいです。
未チェックの例外 システムに使用させるために使用されます 早く失敗する それは良いことです。メソッドが適切に機能するために何を期待しているのかを明確に記述する必要があります。こうすることで、入力を 1 回だけ検証できます。
例えば:
/**
* @params operation - The operation to execute.
* @throws IllegalArgumentException if the operation is "exit"
*/
public final void execute( String operation ) {
if( "exit".equals(operation)){
throw new IllegalArgumentException("I told you not to...");
}
this.operation = operation;
.....
}
private void secretCode(){
// we perform the operation.
// at this point the opreation was validated already.
// so we don't worry that operation is "exit"
.....
}
例を挙げてみましょう。重要なのは、システムにすぐに障害が発生した場合、どこでなぜ障害が発生したかがわかるということです。次のようなスタックトレースが得られます。
IllegalArgumentException: I told you not to use "exit"
at some.package.AClass.execute(Aclass.java:5)
at otherPackage.Otherlass.delegateTheWork(OtherClass.java:4569)
ar ......
そして何が起こったのか分かるでしょう。「delegateTheWork」メソッドの OtherClass (行 4569) は、呼び出す必要がない場合でも、「exit」値を使用してクラスを呼び出しました。
そうしないと、コード全体に検証を散りばめる必要があり、エラーが発生しやすくなります。さらに、何が問題だったのかを追跡するのが難しく、イライラするようなデバッグに何時間もかかることが予想される場合もあります。
NullPointerExceptions でも同じことが起こります。15 個のメソッドを含む 700 行のクラスがあり、30 個の属性を使用し、それらの属性がいずれも null にならない場合、これらの各メソッドで null 可能性を検証する代わりに、これらの属性をすべて読み取り専用にしてコンストラクターで検証することもできます。ファクトリーメソッド。
public static MyClass createInstane( Object data1, Object data2 /* etc */ ){
if( data1 == null ){ throw NullPointerException( "data1 cannot be null"); }
}
// the rest of the methods don't validate data1 anymore.
public void method1(){ // don't worry, nothing is null
....
}
public void method2(){ // don't worry, nothing is null
....
}
public void method3(){ // don't worry, nothing is null
....
}
チェックされた例外 プログラマー (あなたまたはあなたの同僚) がすべて正しく行い、入力を検証し、テストを実行し、すべてのコードが完璧であるにもかかわらず、コードがダウンしている可能性があるサードパーティの Web サービス (またはあなたが使用していたファイル) に接続している場合に役立ちます。使用しているものが別の外部プロセスによって削除されたなど)。接続を試行する前に Web サービスが検証される場合もありますが、データ転送中に問題が発生しました。
そのシナリオでは、あなたやあなたの同僚がそれを助けるためにできることは何もありません。しかしそれでも、アプリケーションがただ死んでユーザーの目の前から消えてしまわないように、何かをしなければなりません。そのためにチェック例外を使用して例外を処理します。そのような場合に何ができるでしょうか? ほとんどの場合、エラーをログに記録しようとするだけで、おそらく作業 (アプリの作業) を保存して、ユーザーにメッセージを表示します。 。( サイト blabla がダウンしています。後で再試行してください。など)
チェックされた例外が (すべてのメソッドのシグネチャに「throw Exception」を追加することによって) 過剰に使用されると、コードは非常に脆弱になります。誰もがその例外を無視するため (一般的すぎるため)、コードの品質は著しく低下します。妥協した。
未チェック例外を使いすぎると、同様のことが起こります。そのコードのユーザーは、大量の try{...}catch( Throwable t ) が表示されるために何か問題が発生するかどうかわかりません。
これが私の「最終的な経験則」です。
私が使う:
- 未チェックの例外 私のメソッドのコード内で 呼び出し側による失敗 (それには 明示的かつ完全なドキュメント)
- チェックされた例外 のために による失敗 着信者 私のコードを使用したい人には明示する必要がある
前の回答と比較すると、これは、どちらか一方 (または両方) の種類の例外を使用するための明確な理論的根拠 (同意することも同意することもできます) です。
これらの両方の例外について、アプリケーション用に独自のチェックなし例外とチェック済み例外を作成します (良い習慣です。 ここで述べたように)、非常に一般的な未チェック例外 (NullPointerException など) を除く
たとえば、以下のこの特定の関数の目的は、オブジェクトを作成する (または、既に存在する場合は取得する) ことです。
意味:
- 作成/取得するオブジェクトのコンテナは存在しなければなりません (呼び出し側の責任)
=> 未チェック例外、およびこの呼び出された関数の javadoc コメントをクリア) - 他のパラメータを null にすることはできません
(それを CALLER に置くコーダーの選択:コーダーは null パラメータをチェックしませんが、コーダーはそれを文書化します) - 結果は NULL にできません
(呼び出し先のコードの責任と選択、呼び出し元にとって非常に興味深い選択
=> チェック例外。オブジェクトが作成できない/見つからない場合、すべての呼び出し元が決定を下さなければならず、その決定はコンパイル時に強制される必要があるためです。この可能性に対処することなくこの機能を使用することはできません。つまり、 チェック済み 例外)。
例:
/**
* Build a folder. <br />
* Folder located under a Parent Folder (either RootFolder or an existing Folder)
* @param aFolderName name of folder
* @param aPVob project vob containing folder (MUST NOT BE NULL)
* @param aParent parent folder containing folder
* (MUST NOT BE NULL, MUST BE IN THE SAME PVOB than aPvob)
* @param aComment comment for folder (MUST NOT BE NULL)
* @return a new folder or an existing one
* @throws CCException if any problems occurs during folder creation
* @throws AssertionFailedException if aParent is not in the same PVob
* @throws NullPointerException if aPVob or aParent or aComment is null
*/
static public Folder makeOrGetFolder(final String aFoldername, final Folder aParent,
final IPVob aPVob, final Comment aComment) throws CCException {
Folder aFolderRes = null;
if (aPVob.equals(aParent.getPVob() == false) {
// UNCHECKED EXCEPTION because the caller failed to live up
// to the documented entry criteria for this function
Assert.isLegal(false, "parent Folder must be in the same PVob than " + aPVob); }
final String ctcmd = "mkfolder " + aComment.getCommentOption() +
" -in " + getPNameFromRepoObject(aParent) + " " + aPVob.getFullName(aFolderName);
final Status st = getCleartool().executeCmd(ctcmd);
if (st.status || StringUtils.strictContains(st.message,"already exists.")) {
aFolderRes = Folder.getFolder(aFolderName, aPVob);
}
else {
// CHECKED EXCEPTION because the callee failed to respect his contract
throw new CCException.Error("Unable to make/get folder '" + aFolderName + "'");
}
return aFolderRes;
}
それは、例外から回復する能力だけの問題ではありません。私の意見では、最も重要なことは、呼び出し元が例外をキャッチすることに関心があるかどうかです。
他の場所で使用するライブラリ、またはアプリケーションの下位層で使用するライブラリを作成する場合は、呼び出し元が例外をキャッチする (知る) ことに興味があるかどうかを自問してください。彼がそうでない場合は、チェックされていない例外を使用して、彼に不必要な負担をかけないようにしてください。
これは多くのフレームワークで使用されている哲学です。特に Spring と Hibernate が思い浮かびます。Java ではチェック例外が過剰に使用されているため、これらは既知のチェック例外を非チェック例外に変換します。私が思いつく例の 1 つは、json.org の JSONException です。これはチェック例外であり、ほとんどの場合迷惑です。これはチェックを解除する必要がありますが、開発者は単純にそれについて考えていません。
ちなみに、ほとんどの場合、例外に対する呼び出し側の関心は、例外から回復する能力と直接相関していますが、常にそうとは限りません。
これは、チェック済み/未チェックのジレンマに対する非常に簡単な解決策です。
ルール 1:未チェック例外は、コードを実行する前にテスト可能な状態であると考えてください。例えば…
x.doSomething(); // the code throws a NullPointerException
ここで、x はヌルです...…コードには次のものが含まれる可能性があります…
if (x==null)
{
//do something below to make sure when x.doSomething() is executed, it won’t throw a NullPointerException.
x = new X();
}
x.doSomething();
ルール 2:チェック例外は、コードの実行中に発生する可能性のあるテスト不可能な状態と考えてください。
Socket s = new Socket(“google.com”, 80);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
…上の例では、DNS サーバーがダウンしているため、URL (google.com) が利用できない可能性があります。DNS サーバーが動作し、「google.com」名を IP アドレスに解決した瞬間でも、google.com に接続されていれば、その後いつでもネットワークがダウンする可能性があります。ストリームの読み取りと書き込みを行う前に常にネットワークをテストすることはできません。
問題があるかどうかを知る前に、コードを実行する必要がある場合があります。開発者に、Checked Exception を介してこれらの状況を強制的に処理するような方法でコードを作成することを強制するということは、この概念を発明した Java の作成者に敬意を表します。
一般に、Java のほぼすべての API は上記の 2 つのルールに従います。ファイルに書き込もうとすると、書き込みが完了する前にディスクがいっぱいになる可能性があります。他のプロセスが原因でディスクがいっぱいになった可能性があります。この状況をテストする方法はまったくありません。いつでもハードウェアの使用に失敗する可能性があるハードウェアを操作する人にとって、Checked Exceptions はこの問題に対する優れた解決策であるように思えます。
これにはグレーゾーンがあります。多くのテストが必要な場合 (多数の && と || を含む驚くような if ステートメント)、スローされる例外は CheckedException になります。これは、正しく理解するのが非常に面倒なためです。この問題を単純に言うことはできません。プログラミングエラーです。テストの数が 10 よりはるかに少ない場合 (例:「if (x == null)」) の場合、プログラマ エラーは UncheckedException になるはずです。
言語通訳者を扱う場合、事態は興味深いものになります。上記のルールによれば、構文エラーはチェック済み例外または未チェック例外とみなされるべきですか?言語の構文を実行前にテストできる場合は、UncheckedException になるべきだと私は主張します。パーソナル コンピューター上でアセンブリ コードを実行する場合と同様に、言語をテストできない場合、構文エラーはチェック済み例外になるはずです。
上記の 2 つのルールにより、どちらを選択するかについての懸念はおそらく 90% 解消されるでしょう。ルールを要約するには、このパターンに従ってください…1)実行するコードを正しく実行する前に実行する前に、例外が発生した場合 - 別名プログラマ エラーの場合、例外は UncheckedException (RuntimeException のサブクラス) である必要があります。2) 実行されるコードが正しく実行されるかどうかを実行前にテストできない場合、例外はチェック例外 (例外のサブクラス) である必要があります。
これをチェック例外またはチェックなし例外と呼ぶことができます。しかし、 両方 例外の種類はプログラマがキャッチできるため、最良の答えは次のとおりです。書く 全て あなたの例外として チェックされていない そしてそれらを文書化します。こうすることで、API を使用する開発者は、その例外をキャッチして何かを実行するかどうかを選択できます。チェック例外は完全に時間の無駄であり、コードを見ると衝撃的な悪夢になります。適切な単体テストを行うと、キャッチして何らかの処理を行う必要がある例外が発生します。
チェックされた例外:クライアントが例外から回復でき、続行したい場合は、チェック例外を使用します。
未チェックの例外:例外の後、クライアントが何もできない場合は、未チェック例外を発生させます。
例:メソッド A() で、A() からの出力に基づいて算術演算を実行する必要がある場合は、別の演算を行う必要があります。実行時に予期しないメソッド A() からの出力が null の場合、実行時例外である Null ポインター例外がスローされることが予想されます。
参照する ここ
私は、特に API を設計する場合、原則としてチェックされない例外を優先することに同意します。呼び出し元は、文書化された未チェックの例外をキャッチすることを常に選択できます。発信者に不必要に強制しないだけです。
実装の詳細として、チェック例外は下位レベルで役立つことがわかりました。多くの場合、指定されたエラー「リターン コード」を管理するよりも、制御メカニズムのフローが優れているように思えます。低レベルのコード変更に対するアイデアの影響を確認するのにも役立つことがあります...ダウンストリームでチェック例外を宣言し、誰が調整する必要があるかを確認します。この最後の点は、ジェネリックが多数ある場合には適用されません。 catch(例外 e) または 例外をスローします とにかく、それは通常、あまりよく考えられていません。
ここで、長年の開発経験を経て得た私の意見を共有したいと思います。
チェックされた例外。これはビジネス ユース ケースまたはコール フローの一部であり、予想されるか予想されないアプリケーション ロジックの一部です。たとえば、接続が拒否された、条件が満たされていないなどです。これを処理し、何が起こったのか、次に何をすべきか (後でもう一度試してくださいなど) の指示を含む対応するメッセージをユーザーに表示する必要があります。私は通常、これを後処理例外または「ユーザー」例外と呼んでいます。
未チェックの例外。これはプログラミング例外の一部であり、ソフトウェア コード プログラミングにおける何らかの間違い (バグ、欠陥) であり、プログラマがドキュメントに従って API を使用する方法を反映しています。外部ライブラリ/フレームワークのドキュメントで、NPE または IllegalArgumentException がスローされるため、ある範囲の null 以外のデータを取得することが期待されていると記載されている場合、プログラマはそれを期待し、ドキュメントに従って API を正しく使用する必要があります。それ以外の場合は、例外がスローされます。私は通常、これを前処理例外または「検証」例外と呼んでいます。
対象者別。ここで、例外が設計された対象者またはグループについて話しましょう (私の意見によると)。
- チェックされた例外。対象者はユーザー/クライアントです。
- 未チェックの例外。対象者は開発者です。言い換えれば、未チェック例外は開発者専用に設計されています。
アプリケーション開発ライフサイクルフェーズごと。
- チェック例外は、アプリケーションが例外的なケースを処理する通常の予想されるメカニズムとして、運用ライフサイクル全体にわたって存在するように設計されています。
- 未チェック例外は、アプリケーションの開発/テストのライフサイクル中にのみ存在するように設計されており、すべての例外はその期間中に修正される必要があり、アプリケーションがすでに運用環境で実行されているときにスローされるべきではありません。
フレームワークが通常未チェック例外 (Spring など) を使用する理由は、フレームワークがアプリケーションのビジネス ロジックを決定できないためです。これをキャッチして独自のロジックを設計するのは開発者次第です。
チェック例外は、呼び出し元に情報を提供する必要がある回復可能なケース (つまり、権限が不十分、ファイルが見つからないなど)。
非チェック例外は、実行時に重大なエラーや予期せぬ状況をユーザーまたはプログラマに通知するために使用されることはほとんどありませんが、使用されることはほとんどありません。他の人が使用するコードやライブラリを作成している場合は、それらをスローしないでください。コンパイラは非チェック例外の捕捉や宣言を強制しないため、他の人はソフトウェアがチェックされていない例外をスローすることを期待していない可能性があります。
例外が期待される可能性が低く、それをキャッチした後でも続行でき、その例外を回避するために何もできない場合は、チェック例外を使用できます。
特定の例外が発生したとき、およびその例外が予期されているが確実ではないときに意味のあることをしたいときはいつでも、チェック例外を使用できます。
例外が異なるレイヤー内を移動する場合、すべてのレイヤーで例外をキャッチする必要はありません。その場合は、実行時例外を使用するか、例外を未チェック例外としてラップできます。
実行時例外は、例外が発生する可能性が最も高く、それ以上進む方法がなく、何も回復できない場合に使用されます。したがって、この場合、その例外に関して予防措置を講じることができます。元:NUllPointerException、ArrayOutofBoundsException。これらのことが起こる可能性が高くなります。このシナリオでは、コーディング中にそのような例外を回避するための予防措置を講じることができます。そうしないと、あらゆる場所に try catch ブロックを記述する必要があります。
より一般的な例外はチェックを外すことができ、一般的ではない例外はチェックされます。
いくつかの質問の例外について考えることができると思います。
なぜ例外が起こるのでしょうか?それが起こったときに私たちは何ができるでしょうか
間違い、バグ。 null オブジェクトのメソッドが呼び出されるなど。
String name = null;
... // some logics
System.out.print(name.length()); // name is still null here
この種の例外はテスト中に修正する必要があります。そうしないと、プロダクションが中断され、すぐに修正する必要がある非常に重大なバグが発生することになります。この種の例外はチェックする必要はありません。
外部からの入力により、 外部サービスの出力を制御したり信頼したりすることはできません。
String name = ExternalService.getName(); // return null
System.out.print(name.length()); // name is null here
ここで、名前が null の場合に続行したい場合は、名前が null かどうかを確認する必要がある場合があります。それ以外の場合は、そのままにしておくことができ、ここで停止し、呼び出し元にランタイム例外が与えられます。この種の例外はチェックする必要はありません。
外部からの実行時例外により、 外部サービスを制御したり信頼したりすることはできません。
ここで、例外が発生したときに続行したい場合は、外部サービスからすべての例外をキャッチする必要がある場合があります。それ以外の場合は、そのままにしておくことができ、ここで停止し、呼び出し元にランタイム例外が与えられます。
外部からのチェック例外により、 外部サービスを制御したり信頼したりすることはできません。
ここで、例外が発生したときに続行したい場合は、外部サービスからすべての例外をキャッチする必要がある場合があります。それ以外の場合は、そのままにしておくことができ、ここで停止し、呼び出し元にランタイム例外が与えられます。
この場合、外部サービスでどのような例外が発生したかを知る必要がありますか? 場合によります:
ある種の例外を処理できる場合は、それらをキャッチして処理する必要があります。他の人については、泡立ててください。
特定の例外に関するログやユーザーへの応答が必要な場合は、それらをキャッチできます。他の人については、泡立ててください。
これら 2 種類の例外は、プログラマーのエラーかどうかに基づいて区別する必要があります。
- エラーがプログラマーエラーである場合、それは未チェック例外である必要があります。. 例えば:SQLException/IOException/NullPointerException。これらの例外は、プログラミングエラーです。これらはプログラマによって処理される必要があります。JDBC APIでは、Sqlexceptionは例外をチェックします。SpringJDBCtemplateでは、未チェックの例外です。
- エラーがプログラマ エラーではなく、その理由が外部からのものである場合、それはチェック例外である必要があります。 例えば:ファイルが削除されているか、他の誰かによってファイルの許可が変更された場合、回復する必要があります。
FileNotFoundException は、微妙な違いを理解するための良い例です。ファイルが見つからない場合は FileNotFoundException がスローされます。この例外には 2 つの理由があります。ファイル パスが開発者によって定義されている場合、または GUI を介してエンド ユーザーから取得されている場合は、未チェック例外になるはずです。ファイルが他の人によって削除された場合、それはチェック済み例外になるはずです。
チェック例外は 2 つの方法で処理できます。これらは try-catch を使用するか、例外を伝播します。例外の伝播の場合、コールスタック内のすべてのメソッドは 固く結ばれた 例外処理のため。だからこそ、Checked Exception は慎重に使用する必要があります。
階層化されたエンタープライズ システムを開発する場合、スローする例外のほとんどは非チェック例外を選択する必要がありますが、何もできない場合にはチェック例外を使用することを忘れないでください。
Application Exceptionを宣言するときは、Unchecked Exception、つまりRuntimeExceptionのサブクラスにする必要があると思います。その理由は、try-catch でアプリケーション コードを乱雑にせず、メソッドで宣言をスローするためです。アプリケーションが Java API を使用している場合は、いずれにせよ処理する必要があるチェック例外をスローします。その他の場合、アプリケーションは未チェック例外をスローする可能性があります。アプリケーションの呼び出し元が未チェック例外を処理する必要がある場合は、それを実行できます。
私が使用するルールは次のとおりです。チェックされていない例外は決して使用しないでください。(または回避方法が見つからない場合)
ライブラリを使用する開発者の観点、またはライブラリ/アプリケーションを使用するエンドユーザーの観点からすると、認識されない例外が原因でアプリケーションがクラッシュすることに直面するのは本当に残念です。また、キャッチオールに頼るのも良くありません。
この方法では、アプリケーションが完全に消えるのではなく、引き続きエラー メッセージがエンド ユーザーに表示されます。