基本的にリストを繰り返し処理し、
- 最初のオブジェクトでメソッドを呼び出します
- 最初の例外をキャッチします (存在する場合)。キャッチする例外がなくなった場合は、通常どおりに戻ります。それ以外の場合は、すべての例外がキャッチされるまでメソッドを呼び出し続けます。
- 次のオブジェクトに移動します。
各オブジェクトを反復処理し、メソッドを呼び出して、1 つの例外をキャッチすることはできますが、メソッドを継続的に呼び出して例外をキャッチし続ける方法がわかりません。
基本的にリストを繰り返し処理し、
- 最初のオブジェクトでメソッドを呼び出します
- 最初の例外をキャッチします (存在する場合)。キャッチする例外がなくなった場合は、通常どおりに戻ります。それ以外の場合は、すべての例外がキャッチされるまでメソッドを呼び出し続けます。
- 次のオブジェクトに移動します。
各オブジェクトを反復処理し、メソッドを呼び出して、1 つの例外をキャッチすることはできますが、メソッドを継続的に呼び出して例外をキャッチし続ける方法がわかりません。
これは他の回答と似ていますが、フラグがないので、私には雑然としているように見えます。でも、よくわからないので、役に立つ場合に備えて捨てています。
for (Item item : items) {
while (true) {
try {
item.doSomething();
break;
} catch (MyException ex) {
log.warn("Something failed.", ex);
}
}
}
このアプローチは、ラベルのないステートメントの操作に依存します。この操作は、突然完了してから、通常どおりbreak
、囲んでいるステートメントを終了します。while
その後のコメントに基づいて、メソッドによってスローされるように宣言された複数の例外がある場合の意味について、多少の混乱があると思います。
メソッドの各呼び出しは、1つの例外がスローされるだけで終了できます。中断したところから呼び出しを再開して、後続の例外を処理することはできません。
したがって、メソッドが複数の例外をスローする場合は、共通の祖先をキャッチして次に進みます。たとえば、メソッドがjava.io.EOFException
または をスローする場合、それは共通の祖先であるため、java.nio.channels.ClosedChannelException
単純にキャッチできます。(または同じ理由でjava.io.IOException
キャッチすることもできます。)同じ条件でメソッドを再度呼び出すと、それ以上は取得できません。java.lang.Exception
java.lang.Throwable
一部が失敗した場合でも、各オブジェクトでメソッドを呼び出そうとする場合は、次を使用します。
for (Item item : items) {
try {
item.doSomething();
} catch (Exception ex) { /* This could be any common ancestor. */
log.warn("Something failed.", ex);
}
}
複数の例外をスローする単一のメソッド呼び出しを処理することについて話している場合、それは実行できません。メソッドを何度呼び出しても、最初の例外がスローされ続けます。メソッドに戻ってそこから実行し続けることはできません。1 つの例外をスローした後、すべてが終了します。
ただし、例外をスローする場合とスローしない場合があるメソッドについて話している場合は、次のようにしてみてください。
boolean thrown = false;
do {
try {
thrown = false;
method();
}
catch (Exception e) {
thrown = true;
// Handle as you like
}
} (while thrown);
これは私が理解していることです。
多くの例外をスローする可能性のあるオブジェクトのメソッドがあります。
やりたいことは、それらをすべてキャッチして、リスト内の次のオブジェクトに進むことです。
あれは正しいですか?
したがって、それは次のようになります。
for( YourObject o : yourList ) {
try {
o.thatMethod();//invoke that risky method
} catch( SomeExceptionClass sec ) {
// Do something with that exception
} catch( SomeOtherExceptionClass soec ) {
// Do something with that exception
} catch( YetAnotherxceptionClass yaec ) {
// Do something with that exception
} catch( OtherUnRelatedException oue ) {
// Do something with that exception
}
}
これを行うと、 の呼び出しがthatMethod()
例外をスローし、その例外がcatch
セクションにリストされている場合、実行フローはその例外にジャンプし、その後通常のフローに進みます (これはfor
ループであり、次のオブジェクトに進みます) )
これが必要なものであることを願っています。詳細については、以下を参照してください: Java チュートリアル セクションの catch ブロック重要なクラス
リスト内のアイテムに対して何らかの検証を実行しようとしていると想定しています。この場合、検証エラーは例外をスローすることによって報告されます。また、すべての検証エラーを収集しようとしていると仮定しています。
簡単な答えは、このアプローチではこの問題を解決できないということです。理由を理解するには、これを見てください。
boolean exceptionCaught = false;
do {
try {
item.doSomething();
} catch (MyException e) {
exceptionCaught = true;
}
} while (exceptionCaught);
呼び出すたびitem.doSomething()
に、まったく同じ場所で例外がスローされるため、これは失敗します。最終的な結果は、無限ループです。
このアプローチでできる最善のことは、リスト内のそれぞれの最初の例外をキャプチャすることです。item
では、達成しようとしているものをどのように達成できますか? 答えは、検証コードを変更して、例外をスローする以外の方法でエラーを報告する必要があるということです。たとえば、次のように変更できます。
class Item {
...
void validate() {
if (noHat) {
throw new MyException("bad hat");
}
if (noPants) {
throw new MyException("world-wide pants");
}
}
}
このようなものに:
class Item {
...
void isValid(List<MyException> errors) {
boolean ok = true;
if (noHat) {
errors.add(new MyException("bad hat"));
ok = false;
}
if (noPants) {
errors.add(new MyException("world-wide pants"));
ok = false;
}
return ok;
}
}
ぐちゃぐちゃか!さまざまな方法でこれを甘やかすことができますが、このスタイルのエラー報告は常により複雑になります。しかし、混乱を避け、すべての検証エラーをキャプチャする実用的な方法はないと思います。