잡는 것이 나쁜 습관 Throwable
입니까?
예를 들면 다음과 같습니다.
try {
// Some code
} catch(Throwable e) {
// handle the exception
}
이것은 나쁜 습관입니까, 아니면 가능한 한 구체적이어야합니까?
답변
가능한 한 구체적이어야합니다. 그렇지 않으면 예상치 못한 버그가 이런 식으로 사라질 수 있습니다.
게다가, Throwable
커버 Error
도 마찬가지이며 일반적으로 반환 지점이 아닙니다 . 당신은 그것을 잡거나 다루고 싶지 않고, 당신은 당신의 프로그램이 즉시 죽어 올바르게 고칠 수 있기를 원합니다.
답변
이것은 나쁜 생각입니다. 사실, 잡는 Exception
것 조차도 일반적으로 나쁜 생각입니다. 예를 들어 보겠습니다.
try {
inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(Throwable e) {
inputNumber = 10; //Default, user did not enter valid number
}
이제 getUserInput ()이 잠시 차단되고 다른 스레드가 최악의 방법으로 스레드를 중지한다고 가정 해 보겠습니다 (thread.stop () 호출). catch 블록은 ThreadDeath
오류 를 포착합니다 . 이것은 매우 나쁩니다. 해당 예외를 포착 한 후 코드의 동작은 거의 정의되지 않았습니다.
예외를 잡는 것과 비슷한 문제가 발생합니다. 아마도getUserInput()
때문에 InterruptException의 실패, 또는 결과, 또는 다른 실패의 모든 종류를 기록하는 동안 권한은 예외를 부인했다. 그 때문에 문제를 해결하는 방법도 모르기 때문에 무엇이 잘못되었는지 전혀 모릅니다.
세 가지 더 나은 옵션이 있습니다.
1-처리 방법을 알고있는 예외를 정확히 포착합니다.
try {
inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(ParseException e) {
inputNumber = 10; //Default, user did not enter valid number
}
2-발생하고 처리 방법을 모르는 예외를 다시 발생시킵니다.
try {
doSomethingMysterious();
} catch(Exception e) {
log.error("Oh man, something bad and mysterious happened",e);
throw e;
}
3-finally 블록을 사용하면 다시 던지는 것을 기억할 필요가 없습니다.
Resources r = null;
try {
r = allocateSomeResources();
doSomething(r);
} finally {
if(r!=null) cleanUpResources(r);
}
답변
또한을 잡을 때 특별한 치료가 필요한 Throwable
잡을 수도 있습니다 InterruptedException
. 자세한 내용 은 InterruptedException 처리 를 참조하십시오.
확인되지 않은 예외 만 포착하려는 경우이 패턴을 고려할 수도 있습니다.
try {
...
} catch (RuntimeException exception) {
//do something
} catch (Error error) {
//do something
}
이렇게하면 코드를 수정하고 확인 된 예외를 throw 할 수있는 메서드 호출을 추가 할 때 컴파일러가이를 상기시켜주고이 경우에 수행 할 작업을 결정할 수 있습니다.
답변
Error 클래스의 javadoc에서 직접 가져온 것입니다 (잡지 않는 것이 좋습니다).
* An <code>Error</code> is a subclass of <code>Throwable</code>
* that indicates serious problems that a reasonable application
* should not try to catch. Most such errors are abnormal conditions.
* The <code>ThreadDeath</code> error, though a "normal" condition,
* is also a subclass of <code>Error</code> because most applications
* should not try to catch it.
* A method is not required to declare in its <code>throws</code>
* clause any subclasses of <code>Error</code> that might be thrown
* during the execution of the method but not caught, since these
* errors are abnormal conditions that should never occur.
*
* @author Frank Yellin
* @version %I%, %G%
* @see java.lang.ThreadDeath
* @since JDK1.0
답변
메서드에서 예외 버블을 절대로 가질 수 없다면 나쁜 습관이 아닙니다.
정말 예외를 처리 할 수 없다면 나쁜 습관입니다. 단순히 catch하고 다시 던지는 것보다 메소드 서명에 “throws”를 추가하는 것이 더 좋으며, 더 나쁜 것은 RuntimeException에 래핑하고 다시 던지는 것입니다.
답변
오류를 지나치게 많이 던지는 라이브러리를 사용하는 경우 Throwable 잡기가 필요할 때가 있습니다. 그렇지 않으면 라이브러리가 애플리케이션을 종료 할 수 있습니다.
그러나 이러한 상황에서는 모든 Throwables가 아니라 라이브러리에서 발생한 특정 오류 만 지정하는 것이 가장 좋습니다.
답변
Throwable은 throw 될 수있는 모든 클래스의 기본 클래스입니다 (예외뿐만 아니라). OutOfMemoryError 또는 KernelError를 포착하면 할 수있는 일이 거의 없습니다 ( java.lang.Error 를 포착하는 경우 참조 )
예외를 잡는 것으로 충분합니다.