2012-03-08 3 views
4

처음부터 예외를 포착하고 재발행하는 것에 비해 이점이 무엇인지 혼란 스럽습니다. 예를 들어Java - 예외 던지기와 예외 잡기 및 재 게시 예외의 차이점

는 대

private void testMethod() throws Exception 
{ 
    //some bad code here 
} 

:

private void testMethod() throws Exception 
{ 
    try 
    { 
     //some bad code here 
    } 
    catch (Exception e) 
    { 
     throw e; 
    } 
} //end testMethod() 

이 오류 메시지의 스택 추적을 보존 할 수 있나요? 예제를 설정하려고했지만 두 출력 사이에 다른 출력이 표시되지 않았습니다.

도움 주셔서 감사합니다.

답변

0

차이는 없습니다. 그것을 다시 던지기 전에 예외 (예외)를 원한다면 말입니다.

0

나는 많은 차이가 있다고 생각하지 않지만, 그것이 가치있는 것이면 나는 첫 번째 것을 선호 할 것입니다.

무언가를 할 수 있거나 예외가 전파되어야하는 경계 (예 : 모든 예외를 잡아내는 웹 컨트롤러 및 사용자를 우호적 인 오류 페이지로 안내하는 라우터) 인 경우가 아니면 예외를 잡아서는 안됩니다.

단순히 잡기와 재사용은 키 입력의 낭비입니다. 정보를 추가하지 않으며 건설적인 일도하지 않습니다.

예외는 확인 된 예외를 catch하고 확인되지 않은 예외로 래핑하는 것입니다. 그렇지 않으면 두 번째 관용구를 피하십시오.

1

이 방법을 사용하면 예외를 수정할 수 있습니다. 예를 들어보다 구체적인 메시지를 줄 수 있습니다. 이와

  • 그것은 (정상적인 상황에서) 추가 이익을 위해 코드를 묶습니다 때문에 일반적으로
  • 에만 시도-catch 블록 곳을 이용해야이 기술을 사용하지 않는해야했다 그것이 실행에게 예외를 잡아 다시 발생하는
1

표준 이유를 늦출 수 있기 때문에 실제로 필요합니다 :

  1. 인시던트 및 예외를 기록하려면 다음을 수행하십시오.
  2. 예외로 인해 일부 정리를 수행합니다 (그러나 종종 finally 블록에서 수행하는 것이 더 좋습니다).
  3. 좀 더 적절한 예외 (즉, processAccount() 메서드가 DbException 대신 AccountException (또는 일부)를 throw하는 것이 더 적절할 수 있습니다.
2

다른 사람들이 말한 것처럼, 귀하의 예에서는 차이가 없으며 두 번째 형식은 피해야합니다.

가끔은 이해할 수있는 유일한 곳은 예외를 잡아서 다른 사람이 위쪽으로 던져 버리는 곳입니다.자바의 예외 처리 구문은 제한되어 있기 때문에, 언젠가 당신은이 작업을 수행 할 수 있습니다 somePieceOfCode이 (Exception 제외)하지만 필요 공통 기본 클래스가없는 다른 체크 된 예외의 수를 던졌습니다 경우가 종종 이루어집니다

try { 
    somePieceOfCode(); 
} catch(RuntimeException e) { 
    throw e; 
} catch(Exception e) { 
    handleException(e); 
} 

같은 방식으로 처리됩니다. NullPointerException 같은 것을 잡을 것이므로 Exception을 붙잡고 싶지 않을 수도 있습니다. 이러한 예외가있는 경우 그럴 수 있습니다.

이 코드는 위쪽으로 모든 RuntimeExceptions 거품을 할 수 있지만, 다른 모든 예외를 처리합니다.

이 관용구는 조금 특이한이며, 모든 사람이 그것을 좋아,하지만 당신은 어떤 장소에서 볼 수 있습니다. 호출 코드는 구현 고유의 문제에 대해 걱정하지 않고, 단지 라이브러리 특정 예외를 잡을 수 있도록 다음 잡기 rethrowing의 주요 장점 중

0

하나는, 다른에서 예외, 도메인 특정 예외를 래핑하는 것입니다. 우리가 최대 절전 모드에서 볼 수있는 예로 -

다른 도서관에서 볼 수있는 당신이 준 예에서 실제 이익, 이러한 혜택 그러나 좋은 예는 없다.

Hibernate는 일반적인 SQLException을 잡아 낸 다음, 그 문제가 무엇인지를보다 잘 설명하는 Hibernate 특정 예외에 랩핑하기 전에 예외를 확인하기 위해 객체를 검사한다.

그러나 예외를 잡아 내고 동일한 예외를 throw하는 경우 가장 먼저 수행해야 할 가능성이 큽니다 (처음에는 예외를 기록 할 수 있습니다).하지만 반드시 사용해야하는 것은 아닙니다. .

5

당신이 개 코드 샘플 사이에 동작의 차이가 없습니다. (특히, 스택 트레이스는 예외가 생성 될 때 기록되고, 던져 질 때 기록되지 않으므로 다시 던진 예외는 여전히 원래 스택 추적을 갖습니다.) 보통, 따라서 사람들은 더 간단한 관용어를 사용합니다. rethrowing은 그 용도가없는 말은 아니다

.

try { 
    // bad code 
} catch (FooBarException e) { 
    throw e; 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

을하거나 예외를 처리 할 수있는 결정은 단순히 유형을 확인하는 것보다 더 복잡 경우, 당신은 단순히 그것을 잡을하고, 경우 다시 발생 할 수 있습니다 : 예를 들어 당신이 FooBarExceptions를 제외한 모든 예외를 처리하기를 원한다면, 당신은 쓸 수 그것은 당신이 그것을 처리 할 수 ​​없습니다 밝혀 :

for (int attempts = 0; attemps < 6; attempts++) { 
    try { 
     return crankyMethod(); 
    } catch (Exception e) { 
     if (fatal(e)) { 
      throw e; 
     } else { 
      // try again 
      continue; 
     } 
    } 
} 

그것은 사람들이 다시 throw를 말할 때, 약간의 평균은 다음 예제와 같이 다른 예외를 던질 것을 주목할 필요가있다 :

for (int i = 0; i < array.length; i++) { 
    try { 
     process(array[i]); 
    } catch (Exception e) { 
     throw new RuntimeException("Could not process element at index " + i, e); 
    } 
} 

이 패턴의 장점은 원본 예외를 관련성이있는 추가 정보로 꾸미는 것입니다 (위의 예에서는 처리 할 수없는 데이터). 원래의 예외는 새 스택의 생성자에 전달되므로 스택 추적은 손실되지 않습니다.