자바 동일한 catch 절에서 여러 Java 예외를 catch 할 수 있습니까?




자바 예외 던지기 (8)

자바에서는 다음과 같이하고 싶다.

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();
}

이 일을 할 수있는 방법이 있습니까?


예외 계층 구조가있는 경우 기본 클래스를 사용하여 예외의 모든 하위 클래스를 catch 할 수 있습니다. 축약 된 경우 다음을 사용하여 모든 Java 예외를 catch 할 수 있습니다.

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

보다 일반적인 경우 RepositoryException이 기본 클래스이고 PathNotFoundException이 파생 클래스이면 다음과 같습니다.

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

위의 코드는 ReceptionException과 PathNotFoundException을 catch하여 한 종류의 예외 처리를 처리하고 다른 모든 예외는 함께 정리합니다. Java 7 이후, @ OscarRyz의 답변에 따라 :

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

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.
  }

예외 계층 구조에서 상위 클래스가되는 예외를 잡아라. 이것은 물론 나쁜 습관 입니다. 귀하의 경우, 일반적인 부모 예외가 Exception 클래스가 발생하고 Exception의 인스턴스 인 예외를 포착하는 것은 실제로 나쁜 관행입니다 - NullPointerException 예외는 일반적으로 프로그래밍 오류이므로 일반적으로 null 값을 확인하여 해결해야합니다.


예. 다음은 파이프 (|) 구분 기호를 사용하는 방법입니다.

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

이것은 Java 7 이후 가능했습니다. 다중 catch 블록의 구문은 다음과 같습니다.

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

그러나 모든 예외가 같은 클래스 계층 구조에 속하면 해당 기본 예외 유형을 간단히 알 수 있습니다.

또한 ExceptionB가 ExceptionA에서 직접 또는 간접적으로 상속 된 경우 동일한 블록에서 ExceptionA와 ExceptionB를 모두 catch 할 수 없습니다. 컴파일러가 불평 할 것이다 :

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

자바 6 (즉, 안드로이드)에 대한 user454322의 답을 대체 할 수있는 클리너 (덜 간단하고 선호하지는 않음)는 모든 Exception 을 잡아서 RuntimeException 다시 던지는 것이다. 스택에 다른 유형의 예외를 잡으려는 경우 (다시 throw하지 않는 한) 체크 된 예외를 효과적으로 잡을 수 있습니다.

예를 들면 :

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 블록 다음에 일부 코드를 실행하는 것이 가장 좋을 수 있습니다.


정확히 Java 7 이전에는 아니지만 다음과 같이 할 수 있습니다.

자바 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();
}

아니, 고객 당 하나.

모든 경우에 동일한 조치를 취하는 한 java.lang.Exception과 같은 수퍼 클래스를 catch 할 수 있습니다.

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

그러나 그것은 최선의 관행이 아닐 수도 있습니다. 실제로 처리 할 전략이있을 때만 예외를 잡아야하며 로깅 및 재발행은 "처리"하지 않습니다. 시정 조치가 없으면 서명을 메서드 서명에 추가하고 상황을 처리 할 수있는 사람에게 거품을 띄게하십시오.





multi-catch