스택 추적을 잃지 않고 Java에서 예외를 다시 발생


417

C #에서는 throw;명령문을 사용 하여 스택 추적을 유지하면서 예외를 다시 발생 시킬 수 있습니다 .

try
{
   ...
}
catch (Exception e)
{
   if (e is FooException)
     throw;
}

Java에 이와 같은 것이 있습니까 ( 원래 스택 추적을 잃지 않습니다 )?


4
왜 원래 스택 트레이스가 느슨하다고 생각합니까? 새로운 SomeOtherException을 던지고 생성자 또는 initCause ()에 근본 원인을 할당하는 것을 잊었을 때 그것을 잃을 수있는 유일한 방법입니다.
— akarnokd

4
이것이 코드가 .Net에서 동작하는 방식이라고 생각하지만 더 이상 긍정적이지 않습니다. 어딘가에서 찾거나 작은 테스트를 실행하는 것이 좋습니다.
— ripper234

11
Throwable던지더라도 수정되지 않습니다. 스택 추적을 업데이트하려면을 호출해야합니다 fillInStackTrace(). 편리하게이 메소드는의 생성자에서 호출됩니다 Throwable.
— Robert

50
C #에서 예, throw e;스택 추적이 손실됩니다. 그러나 Java에서는 아닙니다.
— Tim Goodman

Java 7의 예외에 대한 Oracle의 일부 문서 : 여러 예외 유형
— 포착

답변:


560
catch (WhateverException e) {
    throw e;
}

단순히 잡은 예외를 다시 던질 것입니다 (분명히 주변 메소드는 서명 등을 통해 이것을 허용해야합니다). 예외는 원래 스택 추적을 유지합니다.


4
안녕하세요, InterruptedException e는 throw e 라인을 추가 할 때 처리되지 않은 예외 메시지를 제공합니다. 더 넓은 예외 e로 바꾸면 그렇지 않습니다. 이 작업을 어떻게 올바르게 수행해야합니까?
— James P.

1
@James, 방금 함수 선언에 "throws XxxException"을 추가하면 메시지가 사라지는 것을 관찰했습니다.
— shiouming

2
이러한 재 투입을위한 Java 7 컴파일러는 더 무해합니다. 이제는 메소드를 포함하는 특정 "throws"예외와 함께 잘 작동합니다.
— Waldemar Wosiński

193
@James 만약 당신 catch(Exception e) { throw e; }이 처리되지 않을 것입니다. 당신 catch(InterruptedException ie) { throw ie; }이 처리됩니다. 경험상, catch(Exception e)이건 포켓몬이 아니며, 우리는 모두를 잡기를 원하지 않습니다!
— corsiKa

3
@corsiKa "모두 잡기"를 원하지 않는다는 것이 반드시 사실은 아니며, 다른 사용 사례 일뿐입니다. 적어도 RuntimeException을 잡아서 기록하지 않으면 최상위 루프 또는 이벤트 처리기 (예 : 스레드 실행 내부)가있는 경우 예외를 완전히 놓치지 않고 중요한 루프에서 자동으로 중단됩니다. 종종 일회성 실패입니다. 추가 코드가 무엇을하거나 던질 지 모르는 플러그인 기능에도 정말 좋습니다. 이러한 잡기와 같은 하향식 용도의 경우 예외는 종종 좋은 아이디어 일뿐만 아니라 모범 사례입니다.
— Bill K

82

내가 선호하는:

try
{
    ...
}
catch (FooException fe){
   throw fe;
}
catch (Exception e)
{
    // Note: don't catch all exceptions like this unless you know what you
    // are doing.
    ...
}

6
Java에서 일반적인 예외 및 확인 이외의 특정 예외를 포착하는 것이 확실합니다. +1
— amischiefr

8
당신이하고있는 일을 알지 못한다면 평범한 "예외"를 포착해서는 안되기 때문에 -1.
— Stroboskop

19
@Stroboskop : 사실이지만 대답하려면 질문과 동일한 (유사한) 코드를 사용하는 것이 가장 좋습니다!
— user85421

14
때로는 모든 예외를 잡는 것이 좋습니다. 테스트 사례를 작성하는 경우 등 또는 로깅 목적으로. 또는 잡히지 않는 곳에서는 충돌이 발생합니다.
— John Henckel

1
@JohnHenckel 및 기타 : 유효한 점수가 표시됩니다. 대부분의 경우 (모두는 아님) 잡기 Exception가 일반적으로 옳지 않다는 것을 분명히하기 위해 질문을 업데이트 했습니다 .
— Per Lundberg

74

또한 예외를 다른 예외로 랩핑하고 원인 매개 변수로 Exception을 Throwable로 전달하여 원래 스택 추적을 유지할 수 있습니다.

try
{
   ...
}
catch (Exception e)
{
     throw new YourOwnException(e);
}

8
또한throw new YourOwnException("Error while trying to ....", e);
— Julien

이것은 내가 찾던 것, 특히 당신이 당신의 자신의 메시지를 전달할 수있는 첫 번째 코멘트의 버전
— Csaba

이것은 오류 메시지를 올바르게 표시하지만 스택 추적은 오류 행을 예외를 발생시킨 원래 행이 아닌 'throw new ....... (e)'가있는 행으로 표시합니다.
— Ashburn RK

22

Java에서는 거의 동일합니다.

try
{
   ...
}
catch (Exception e)
{
   if (e instanceof FooException)
     throw e;
}

5
새 예외 객체를 인스턴스화하지 않는 한 스택 추적은 동일하게 유지됩니다.
— Mnementh

28
FooException에 대한 특정 캐치를 추가합니다
— dfa

3
이 특정 경우에 동의하지만 특정 캐치를 추가하는 것이 올바른 선택이 아닐 수 있습니다. 모든 예외에 대한 공통 코드가 있고 특정 예외에 대해 다시 던질 것이라고 상상해보십시오.
— 송아지

1
@MarkusLausberg 그러나 마침내 예외를 잡을 수는 없습니다.
— Robert

예, 그러나 이것은 질문이 아닙니다.
— Markus Lausberg

14

Java에서는 잡은 예외를 그냥 던지기 throw e보다는 던져 버립니다 throw. Java는 스택 추적을 유지 관리합니다.


6

이 같은

try 
{
  ...
}
catch (FooException e) 
{
  throw e;
}
catch (Exception e)
{
  ...
}

5
public int read(byte[] a) throws IOException {
    try {
        return in.read(a);
    } catch (final Throwable t) {
        /* can do something here, like  in=null;  */
        throw t;
    }
}

이것은 메소드가를 던지는 구체적인 예 IOException입니다. final수단 t에만 try 블록에서 던진 예외를 보유 할 수 있습니다. 추가 자료는 여기 및 여기 에서 찾을 수 있습니다 .



3

잡은 excetion을 다른 예외로 랩핑하거나 (더 많은 정보를 제공하기 위해) 잡은 excetion을 다시 던지면 스택 추적이 보존됩니다.

try{ ... }catch (FooException e){ throw new BarException("Some usefull info", e); }


2

내 코드에서 잠재적으로 다시 던지기를 원하는 여러 가지 예외가 발생할 가능성이 비슷한 상황이 발생했습니다. Eclipse가 처리되지 않은 throw e;예외로 이어진다 고 말했기 때문에 위에서 설명한 솔루션 이 효과가 없었습니다.

try
{
...
} catch (NoSuchMethodException | SecurityException | IllegalAccessException e) {                    
    throw new RuntimeException(e.getClass().getName() + ": " + e.getMessage() + "\n" + e.getStackTrace().toString());
}

나를 위해 일했다 .... :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.