이 질문에는 이미 답변이 있습니다.
일부 레거시 코드에서 오버런 예외가 잡히고 다시 던져지는 것을 보았습니다. 이것은 좋은 연습입니까? 그렇다throw e;
동일한 예외를 재발행하거나 새 예외를 만들 수 있습니까?
catch (Exception e) {
StringBuilder sb = new StringBuilder(
"Oops. Something went wrong with id: ");
sb.append(id);
sb.append(". Exception is: ");
sb.append(e.toString());
System.out.println(sb.toString());
throw e;
}
throw e
동일한 예외를 다시 제기하고 있습니다. 최소한 원래 스택 추적을 유지합니다. 일어난 일에 대한 정보를 기록한 stdout에 메시지를 쓰는 것만으로 원래의 예외가 진행되도록합니다.
중대한 장소는 아니며 중앙 지점에 예외를 기록하고 스택 트레이스를 기록하기에 충분해야합니다. 더 많은 정보를 추가해야하는 경우 (예제에서 ID를 기록하는 위치) 새 예외에서 원래의 예외를 원인으로 중첩 한 다음 새 예외를 throw하는 것이 좋습니다. 아마도 중앙 집중식 로깅이 없거나 예외가 어딘가에서 먹는 경향이있는 상황에서 발생했을 것입니다.
rethrowing
다른 클라이언트가 이러한 예외를 다르게 처리하려고 시도 할 수 있으므로 예외가 실제로 좋을 수 있습니다. 동의하지 않습니까? - Prateek
이것은 대개 나쁜 습관입니다.catch(Exception e)
(때때로포켓몬 예외 처리언제너 모두 잡을거야.) 잡기...마다단일 예외. 이러한 예외 처리는 다음과 같은 이유로 거의 유용하지 않습니다.
지금 서명 방법입니다.public void whatever() throws Exception
, 이는 거의 유용하지 않습니다. 이제 사슬을 따라 올라가는 모든 것이 어떤 종류의 예외를 던지는지 전혀 알 수 없습니다. 그들은해야 할 것이다.instanceof
특정 예외를 포착하는 목적을 완전히 무효로하는 수표
두 번째 예외 사항에 관한 한,throw e;
같은 예외 객체를 던집니다. 예외를 래핑하고 싶다면 새 예외를 만들 수 있습니다. 즉, 다음과 같은 작업을 수행 할 수 있습니다.throw new MyCustomException(e);
. 또한 메소드 서명을 변경해야합니다.
더 이상 사슬의 위로 아무것도 없다면, 나는 이것이 나쁘지는 않다는 것을 짐작할 수 있습니다 (그래도 여전히 크지는 않습니다). 그것은 던져진 모든 예외를 기록하려고 시도하는 메서드처럼 보입니다. 그러나, 다시, 이것을하는 더 나은 방법이 있습니다.
내 최선의 추측은 보호의 두 계층을 가지고 노력하는 것입니다. 오류 메시지가 표시되는지 확인하고 클라이언트가 원하는대로 예외를 처리하도록 요청하십시오.catch
절은 예외로부터 복구하기 위해 아무 것도하지 않습니다.
나는 그것을 좋거나 나쁜 습관으로 생각하지 않을 것이다. 요구 사항에 따라 API를 사용하는 100 개의 다른 클라이언트가있는 것처럼 어느 쪽이든 이동하는 것을 고려할 수 있으며 각각의 클라이언트는 서로 다른 방법으로 복구 할 수 있습니다.exception
. 무엇이 잘못되었는지를 표시함으로써 클라이언트가 클라이언트를 처리하는 방법을 결정하는 레이어 바로 아래에 기본 액션 레이어를 추가합니다.exception
.
이제 질문으로 돌아가십시오. 나는 생각한다.throw e
같은 예외 객체를 던집니다. 예외는 다음과 같습니다.objects
자바에서 당신은new exception object
할 수 있기 전에throw
그것은 내가 당신의 코드에서 일어나는 것을 볼 수 없습니다.
throw e
동일한 예외가 발생합니다. 이 일을하는 이유가 있었을 지 모르지만 그렇게 할 이유가 있습니다. 예제 코드에서는 다음에 메시지가 전송됩니다.System.out
, 나중에 스택 추적이 인쇄 된 경우System.err
, 그것은 syncronized되지 않을 것이며, 실제로 두 사람이 귀하의 콘솔에 짜여진 수 있습니다.
보다 나은 접근 방법은 다음과 같습니다.
catch (Exception e) {
StringBuilder sb = new StringBuilder(
"Oops. Something went wrong with id: ");
sb.append(id);
sb.append(". Exception is: ");
sb.append(e.toString());
throw new Exception(sb.toString(), e); // The original exception is an argument
}
이렇게하면 새로운Exception
수정 된 메시지와 함께Exception
디버깅에 도움이되는 스택 추적에.
그것은 좋은 연습 일 수 있습니다. 나는 항상 변환을 사용한다고 생각합니다.RuntimeException
초 동안. 필요하다면 더 나은 예외 처리로 변경할 수 있습니다. 이 목적을 위해 구아바에 유틸리티 클래스가 있습니다.쓰레기이것은 예외 전파를 만든다.
귀하의 경우에는 예외가 있어야하지만런타임 예외로 변환왜냐하면 일반적인 것을 던지는 메소드를 선언했기 때문입니다.Exception
throw하는 메소드와 똑같습니다.RuntimeException
전화하는 사람에게. 첫 번째 경우에는 '모든 것을 잡다', 후자에서는'아무것도 잡는다.'. 아직 실제 응용 프로그램에서이 두 가지의 차이점을 경험하지 못했습니다. 그래서 나는 더 좋아한다.RuntimeException
그들은 타이핑이 덜 필요하기 때문에.
매력 있는 것Exception
Error
그러나 왼쪽)매력 있는 것RuntimeException
RuntimeException
- 이것은또한 많이내 요점은 당신이Exception
당신은이 모든 경우를 정말로 다룰 수 없습니다. 따라서 전화를 걸면 더 적은 타이핑을하는 것 외에는 아무런 차이가 없습니다.RuntimeException
.
Exception
던지기와 같지 않다.RuntimeException
. 전자가 검사되므로 메소드 서명에서 언급해야합니다. 하위 클래스 인 모든 예외Exception
그러나아니의 하위 클래스RuntimeException
확인 된 예외입니다. - Vivin PaliathException
& # 39; 모든 것을 포착 함 & quot;을 의미합니다. 매력 있는 것RuntimeException
'무엇이든 잡는 중'을 의미합니다. 나는 아직 두 가지 경우의 실제 차이를 보지 못했습니다. - Andrey ChaschevException
호출자는 메서드를 처리하거나 다시 throw해야하지만 호출자는 메서드가 throw되고있는 경우 호출을 수행하지 않아도됩니다.RuntimeException
. 또한 잡기RuntimeException
'무엇이든 잡는 중'을 의미하지 않습니다. 그것만서브 클래스 인 그러한 예외를 캐치합니다.RuntimeException
(과RuntimeException
그 자체); 확인 된 예외는 발견되지 않습니다. - Vivin PaliathException
자바의 나쁜 습관이기 때문에 현실 세계의 예를 생각하기가 정말 어려울 것입니다. 전파RuntimeException
그러나 반 패턴이 될 수는 없으며 좋은 연습이 될 수 있습니다. - Andrey Chaschev