web-dev-qa-db-ja.com

同じcatch句で複数のJava例外を捕捉できますか?

Javaでは、私はこのようなことをしたいです。

try {
    ...     
} catch (/* code to catch IllegalArgumentException, SecurityException, 
            IllegalAccessException, and NoSuchFieldException at the same time */) {
   someCode();
}

...の代わりに:

try {
    ...     
} catch (IllegalArgumentException e) {
    someCode();
} catch (SecurityException e) {
    someCode();
} catch (IllegalAccessException e) {
    someCode();
} catch (NoSuchFieldException e) {
    someCode();
}

これを行う方法はありますか?

633
froadie

これは可能でした Java 7以降 。マルチキャッチブロックの構文は次のとおりです。

try { 
  ...
} catch (IOException | SQLException ex) { 
  ...
}

ただし、すべての例外が同じクラス階層に属している場合は、単にその基本例外タイプをキャッチすることができます。

また、ExceptionAから直接または間接的にExceptionBが継承されている場合、ExceptionAとExceptionBの両方を同じブロック内で捕捉することはできません。コンパイラは文句を言うでしょう:

Alternatives in a multi-catch statement cannot be related by subclassing
  Alternative ExceptionB is a subclass of alternative ExceptionA
1034
OscarRyz

Java 7より前ではありませんが、次のようにします。

Java 6以前

try {
  //.....
} catch (Exception exc) {
  if (exc instanceof IllegalArgumentException || exc instanceof SecurityException || 
     exc instanceof IllegalAccessException || exc instanceof NoSuchFieldException ) {

     someCode();

  } else if (exc instanceof RuntimeException) {
     throw (RuntimeException) exc;     

  } else {
    throw new RuntimeException(exc);
  }

}



Java 7

try {
  //.....
} catch ( IllegalArgumentException | SecurityException |
         IllegalAccessException |NoSuchFieldException exc) {
  someCode();
}
102
user454322

Java 7では、次のように複数のcatch句を定義できます。

catch (IllegalArgumentException | SecurityException e)
{
    ...
}
23
crusam

いいえ、顧客ごとに1つです。

すべての場合に同じアクションを実行する限り、Java.lang.Exceptionのようなスーパークラスをキャッチすることができます。

try {
    // some code
} catch(Exception e) { //All exceptions are caught here as all are inheriting Java.lang.Exception
    e.printStackTrace();
}

しかし、それはベストプラクティスではないかもしれません。実際にそれを処理するための戦略があるときだけ例外をキャッチするべきです - そして伐採と再投げは「それを処理する」のではありません。是正処置がない場合は、それをメソッドのシグネチャに追加して、状況を処理できる人に追加してください。

15
duffymo

例外の階層がある場合は、基本クラスを使用してすべてのサブクラスの例外をキャッチすることができます。縮退した場合は、 all / Java例外をキャッチすることができます。

try {
   ...
} catch (Exception e) {
   someCode();
}

より一般的なケースでは、RepositoryExceptionが基本クラスでPathNotFoundExceptionが派生クラスの場合

try {
   ...
} catch (RepositoryException re) {
   someCode();
} catch (Exception e) {
   someCode();
}

上記のコードは、ある種類の例外処理に対してRepositoryExceptionとPathNotFoundExceptionをキャッチし、その他のすべての例外はまとめられます。 Java 7以降、上記の@ OscarRyzの答えのとおり、

try { 
  ...
} catch( IOException | SQLException ex ) { 
  ...
}
13
Michael Shopsin

Java 6(つまりAndroid)に対するuser 454322の回答に代わる、よりクリーン(ただし冗長ではない、おそらくあまり好まれない)の代替案は、すべてのExceptionをキャッチしてRuntimeExceptionを再スローすることです。他のタイプの例外をさらにスタックの上位にキャッチすることを計画している場合(これも再スローしない限り)、これは機能しませんが、事実上すべての checked 例外をキャッチします。

例えば:

try {
    // CODE THAT THROWS EXCEPTION
} catch (Exception e) {
    if (e instanceof RuntimeException) {
        // this exception was not expected, so re-throw it
        throw e;
    } else {
        // YOUR CODE FOR ALL CHECKED EXCEPTIONS
    } 
}

そうは言っても、冗長性のためには、ブール値またはその他の変数を設定し、それに基づいてtry-catchブロックの後にコードを実行するのが最善の方法です。

10
Oleg Vaskevich

7より前のバージョンではどうですか。

  Boolean   caught = true;
  Exception e;
  try {
     ...
     caught = false;
  } catch (TransformerException te) {
     e = te;
  } catch (SocketException se) {
     e = se;
  } catch (IOException ie) {
     e = ie;
  }
  if (caught) {
     someCode(); // You can reference Exception e here.
  }
3
Bill S

例外階層の親クラスになっている例外をキャッチします。 もちろんこれは悪い習慣です 。あなたの場合、共通の親例外はたまたまExceptionクラスであり、Exceptionのインスタンスである例外をキャッチすることは実際には悪い習慣です。

0
Vineet Reynolds

はい。これは、パイプ(|)セパレータを使う方法です。

try
{
    .......
}    
catch
{
    catch(IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e)
}
0
Shiva