新しい例外の代わりに Throwable を使用する必要があるのはどのような場合ですか?
質問
与えられる: Throwable
は Exception
のスーパークラス。
独自の「例外」の作成に関するテキストを読むと、次の例が表示されます。 Throwable
で使用されています catch
ブロックと他のテキストが表示されます new Exception()
で使用されています catch
ブロック。それぞれをいつ使用するべきかについての説明はまだ見ていません。
私の質問はこれです。いつ行うべきですか Throwable
いつ使用するべきか new Exception()
利用される?
内部 catch
または else
次のいずれかを使用してブロックします。
throw throwable;
または
throw new Exception();
解決
(コメントから)これを提起した問題は、コレクションが構築されない場合、同僚が構築しているコードに「例外」を渡す必要があるということです。
その場合は、 チェックされた例外. 。投げることもできます Exception
, 、その適切な既存のサブクラス (ただし、 RuntimeException
とそのサブクラス チェックされていない)、またはカスタムサブクラス Exception
(例えば。」CollectionBuildException
")。を参照してください。 例外に関する Java チュートリアル Java 例外を理解するために。
他のヒント
常に投げる Exception
(決して Throwable
)。普通は釣れないよね Throwable
どちらでも構いませんが、できます。Throwable はスーパークラスです Exception
そして Error
, 、だからあなたは捕まえるでしょう Throwable
捕まえるだけでなく Exception
でも Error
それがそれを持つことのポイントです。問題は、 Error
は通常、通常のアプリケーションではキャッチできず、キャッチすべきではないものなので、単に使用してください Exception
特別に使用する理由がない限り、 Throwable
.
実際に例外をキャッチして、「新しい例外」と同じくらい一般的な新しい例外をスローするべきではありません。
代わりに、例外をバブルアップしたい場合は、次の手順を実行してください。
try {
// Do some stuff here
}
catch (DivideByZeroException e) {
System.out.println("Can't divide by Zero!");
}
catch (IndexOutOfRangeException e) {
// catch the exception
System.out.println("No matching element found.");
}
catch (Throwable e) {
throw e; // rethrow the exception/error that occurred
}
元の例外の原因を回避するのに十分なコンテキストを提供する有用なカスタム例外を発生させない限り、例外をキャッチして、コード ブロックに対して発生した例外の代わりに新しい例外をスローすることは、良い習慣ではないと私は考えています。 。
この単語が表示されるのは 2 か所だけです Throwable
コード内:
public static void main(String args[])
{
try
{
// Do some stuff
}
catch(Throwable t)
{
}
}
そして
public class SomeServlet extends HttpServlet
{
public void doPost(HttpRequest request, HttpResponse response)
{
try
{
// Do some stuff
}
catch (Throwable t)
{
// Log
}
}
}
Throwable はクラスではなくインターフェイスです。 Throwable、Exception、Error の 2 つのクラスが拡張されています。
ルールは次のとおりです。例外をキャッチするときは、できるだけ具体的にします。つまり、たとえば、Throwable の代わりに Exception をキャッチしたり、Exception の代わりに IOException をキャッチしたりすることを意味します。
エラーをキャッチしないでください - エラーはバグです。代わりにコードを修正してください。
絶対にすべてをキャッチする必要がある場合は、「catch Throwable」を使用しますが、これは悪い形式です。
throw new Exception();
それはあなたがすべきことです 一度もない catch ブロックで実行しますが、throw を実行する必要がある、または実行したい場合があります。 new SomeException(throwable);
(完全なスタック トレースを保存) の代わりに throw throwable;
メソッドの API に準拠するため。投げると宣言したとき SomeException
しかし、あなたはスローする可能性のあるコードを呼び出しています IOException
メソッドに追加したくないもの throws
句。
おそらく最も一般的なケースは次のとおりです new RuntimeException(throwable);
を避けるために throws
全くの条項。多くの人は、チェック例外を使用する必要があるため、これはひどい乱用だと言うでしょう。私の意見では、それらは間違いであり、チェック例外は Java 言語設計の間違いであり、醜くて保守不可能なコードを生み出すだけです。
Java が最初に登場したときに聞いた話ですが、Throwable は例外以外の場合の制御の転送に使用される可能性があるという理論でした。ただし、そのように使用されているのを見たことはありません(そして、それはおそらく非常に良いことです)。
したがって、例外 (あるいは、より詳細な例外) をキャッチするだけです。
Throwable は、プログラムのコンテナまたはメイン ループによってのみキャッチされることを目的としています。ほとんどの場合、Error などの例外以下のものをキャッチしても、プログラムに大きな機能は追加されません。結局のところ、VirtualError やその他の Error がスローされた場合に何ができるでしょうか。ログを記録して続行すること以外は、あまり多くはありません。
すべての例外は最終的には問題になります...エラーはバグだと言っても何の意味もありません。
エラーはバグではなく、ホスト VM で発生している問題です (例: OutOfMemoryError)。例外は、現在の操作が失敗したことを通知し、場合によっては何らかの診断を提供するために使用できる手段です。
通常、Throwable をスローしたりキャッチしたりすることはありません。特に、JVM エラー ( Error() を拡張するもの) は、 意味 奇妙なシステムレベルの作業を行っていない限り、ユーザーコードに捕らえられることはありません。
「Throwable」を言語アーティファクトとして扱います。「Exception」クラスは、プログラマがコード ブロックを「例外的に」終了する場合、つまり正常に終了しない、または値を返さない場合に使用することを目的としているため、その名前が付けられています。
これには、通常のエラー状況 (「通常」とは、JVM エラーとは対照的にという意味です) と、制御メカニズムとして例外を使用している場所の両方が含まれます。
例外を「戻り値の型」として使用するべきではありません...
スローしている条件が一般的な場合、その条件を呼び出し側ルーチンに返すために大量のリソースを費やすことになります。例外の構築にはコストがかかります。
たとえば、例外を「ネガティブ」としてスローするタイトなループが発生するケースを見てきました。ID の割り当て、このルーチンは CPU 時間の約 99% を占めました。代わりに文書化された戻り定数に変更すると、これは 25% に低下しました。