2012-03-20 2 views
29

java.lang.ThrowablefillInStackTrace 방법이 궁금한가요?Throwable.fillInStackTrace() 메서드가 공개되어있는 이유는 무엇입니까? 왜 누군가 그것을 사용합니까?

이 메서드는 원본 스택 추적을 호출 된 곳의 추적으로 대체하여 예외를 지역화하는 데 필요한 정보를 제거합니다. 난독 화를 위해 사용될 수는 있지만 새로운 스택 추적이 난독 화 코드로 전달되므로 많은 노력을 기울이지 않아도됩니다. 더 나은 방법은 단순히 예외를 숨기거나 새 예외를 던지기 만하면됩니다.

그러나 합리적인 기존 Throwable에이 메서드를 호출하는 경우를 찾을 수 없습니다. 그래서 질문은 : 왜이 ​​방법이 공개인가? 뒤에 감각이 있습니까?

답변

36

하나의 이유는 성능 때문입니다. 던지기 및 예외 잡기는 저렴합니다. 비싼 부분은 filling in the stack trace입니다. fillInStackTrace()을 무시하면 아무 일도 일어나지 않지만 예외를 만들면 값이 싸집니다.

저렴한 예외를 사용하면 flow control에 대한 예외를 사용할 수 있습니다.이 경우 특정 상황에서 코드를 더 쉽게 읽을 수 있습니다. more advanced flow control이 필요한 곳에 JVM 언어를 구현할 때 사용할 수 있으며 actors library을 작성하는 경우 유용합니다.

+0

이것은 흥미 롭지 만, 예외를 통해 흐름을 제어하는 ​​Java의 개념은 아닙니다. –

+1

일반적으로 네,하지만 링크를 따라 가는지 알 수 있듯이 때로는 매우 유용합니다. – sbridges

+3

나는이 사용이 디자이너의 의도라고 의심한다. – Attila

4

승인되지 않은 사용자로부터 응용 프로그램의 세부 정보를 숨기는 하나의 합당한 사례입니다. 예를 들어 라이센스 키가 만료되면 해커의 작업을 단순화하기 때문에 던져진 예외의 스택 추적을 노출하고 싶지 않습니다.

+1

그런데 왜 스택 추적을 표시합니까? –

+0

@lechlukasz - 스택 추적을 표시하지 않아도됩니다. 때로는 모든 예외가 인쇄되는 로그 파일을 체크 아웃하는 것으로 충분합니다. BTW 나는 개인적으로 (스포츠 관심사를 위해) 몇몇 보호 한 신청을 끊고 그들이이 간계를 난처함에 추가로 사용했다는 것을 보았다. – AlexR

18

하나의 합법적 인 사용은 실제로 던지고있는 곳과 다른 곳에서 예외를 만드는 것입니다. 예를 들어, 사용자 정의 예외를 생성하기위한 플러그인 기능을 제공하는 응용 프로그램이있을 수 있습니다. stacktrace가에 으로 채워지기 때문에 예외 추적에는 오해의 소지가있는 정보 (사용자 지정 예외 팩토리에 대한 호출이 포함될 수 있음)가 포함됩니다. 따라서 사용자 정의 팩토리에서 생성 후 예외에 대해 fillInStackTrace()을 호출하면 최종 예외 수신자에게보다 정확한 스택 추적을 제공 할 수 있습니다.

rejected bug은이 방법의 필요성으로 인해 혼란스러운 사람이 아님을 나타냅니다.

1

유사하게 question이 답을 제공합니다.

기본적으로 JLS에 따르면 예외 추적시 스택 추적이 채워집니다. 그러나 스택을 재사용 할 때 좀 더 유용한 위치로 스택을 "재설정"할 수도 있습니다.

이 기능을 허용하려면, 우리는이에 fillInStackTrace()

편집

음, 오늘은 자바 표준 라이브러리의 사양은 두 번째의 서문으로 개정 1. 후 JLS에서 제거 배웠다 버전 상태 :

이와 같이, 우리는 실제로 javadoc을보다 자세히 살펴볼 필요가 있습니다. API는 놀랍게도 느슨합니다.전체 관련 부분은 내용의 헤더에서 다음과 같습니다

Instances of two subclasses, Error and Exception, are conventionally used to indicate 
that exceptional situations have occurred. Typically, these instances are freshly 
created in the context of the exceptional situation so as to include relevant 
information (such as stack trace data). 

그리고 java.lang.Throwable.printStackTrace은() 내 믿음이 VM의 구현을 제공 할 수 있도록하는 것입니다

Prints this throwable and its backtrace to the standard error stream. 

무엇이든 자신의 상황에 가장 적합한/적절한 구현입니다. 이 컨텍스트에서 명시적인 fillInStackTrace() public을 사용하면 훨씬 더 의미가 있습니다.

기본적으로 가상 시스템은 최선의 백 트레이스 위치를 제공합니다. fillInStackTrace() public을 사용하면 개발자가 더 세분화 할 수 있습니다.

-

일 최종 편집 :

내가 relevant bits of the JLS First Edition에 남아있는 링크를 추적 관리하고 나는 방법은 공개 왜 하나 더 이유를 제공하고 싶습니다. 그것은 Java에 대한 공통된 설명보다 좋거나 나 빠릅니다.

항상 이런 식이었습니다.

+0

jtahlborn이이 질문에 대한 답변을 넘어 귀하의 링크 뒤에 어떤 추가 정보가 있는지 설명해 주시겠습니까? JLS는'fillInStackTrace'의 사용에 관해서 아무것도 말하지 않습니까? –

1

아마도 예외를 catch하고 이전 예외를 캡슐화하지 않는 새 예외를 throw하려고합니다. 잡힌 스택에서 getStackTrace를 실행하고 새 스택에 대해 stackTrace를 설정하십시오. 여러 번 발생합니다

private static Exception theException = new MyException(); 

: 당신이 싱글 예외가있을 때

도 같이 한 번 인스턴스화, 작동합니다. 이렇게하면 매번 새로운 예외를 비싸게 생성 할 필요없이 catch 된 예외와 관련된 무언가로 stackTrack을 설정할 수 있습니다. 이것이 스칼라가 어떻게 계속하고 깨지는지를 생각합니다. 이 (즉, 스레드) 동시에 여러 번 발생 될 수있는 경우 까다로운 일이 될 수있는 정적 예외를 사용

try { 
    .... 
} catch (OtherException oe) { 
    theException.fillStackTrace(oe.getStackTrace()); 
    theException.setMessage(...); //etc 
    throw theException; 
} 

+1

기껏해야 이것은 코드 난독 화입니다. 예외는 불변 인 것처럼 처리되어야합니다. OtherException은 새 예외의 원인으로 간단하게 래핑되어야합니다. 스칼라는 비 로컬 흐름 제어를 위해 빈 스택 추적을 사용하는데, 이는 내 포스트에서 설명한 것과 같은 이유로 다른 예제이다. –

+0

예외는 변경할 수 없으므로 실제로 정적에 할당하고 싶지는 않습니다. –

5

Throwable.fillInStackTrace()에 대한 하나의 합법적 인 사용 사례는 로컬이 아닌 제어 흐름입니다 :

예를 들어, 내 TrueZIP 프레임 워크 내에서 파일 시스템 컨트롤러에 복잡한 데코레이터 체인을 사용합니다. 이 체인의 컨트롤러 중 하나는 FsLockController 클래스의 인스턴스입니다. 이 객체는 파일 시스템에 대한 ReentrantReadWriteLock을 관리합니다. 이제이 체인의 더 깊은 곳에있는 파일 시스템 컨트롤러는 쓰기 잠금이 필요하지만 FsLockController가 읽기 잠금 만 획득했음을 감지 할 수 있습니다. 데드 록을 사용하지 않고 읽기 잠금을 쓰기 잠금으로 업그레이드 할 수 없으므로 FsNeedsWriteLockException 클래스의 인스턴스로 예외가 발생해야합니다. 그런 다음 FsLockController를 장식하면이 예외를 catch하고 읽기 잠금을 해제하고 쓰기 잠금을 획득 한 다음 작업을 다시 시도합니다.

이런 종류의 로컬 컨트롤 흐름은 실제로 잘 작동하지만 고려해야 할 것이 하나 있습니다. 예외를 던지고 잡는 것은 저렴하지만 스택 채우기를 채우거나 스택 추적을 검사하는 것은 비용이 많이 듭니다. 이제이 특정 예외 유형이 단독으로이 파일 시스템 컨트롤러 체인 내에서 처리되고 catch되기 때문에 스택 추적이 전혀 필요하지 않으므로이 비싼 작업을 억제하기 위해 Throwable.fillInStackTrace()를 빈 메서드 본문으로 안전하게 재정의 할 수 있습니다. .

이 예외 유형의 기본 클래스 소스 코드는 here으로 볼 수 있습니다.

관련 문제