답변:
일반적으로 결코.
그러나 때로는 특정 오류를 포착해야합니다.
프레임 워크와 같은 코드를 작성하는 경우 (타사 클래스로드), 잡는 것이 현명 할 수 있습니다. LinkageError
(클래스 정의 없음, 만족스럽지 않은 링크, 호환되지 않는 클래스 변경).
나는 또한의 서브 클래스를 던지는 어리석은 써드 파티 코드를 보았습니다 Error
.
그건 그렇고,에서 복구 할 수 없는지 잘 모르겠습니다 OutOfMemoryError
.
못. 응용 프로그램이 다음 코드 줄을 실행할 수 있는지 확신 할 수 없습니다. 를 받으면 어떤 일이든 안정적으로 할 수 있다는 보장OutOfMemoryError
이 없습니다 . RuntimeException을 잡아 예외를 확인했지만 오류는 확인하지 않았습니다.
boolean assertionsEnabled = false; assert assertionsEnabled = true;
일반적으로 항상 java.lang.Error
로그에 기록하거나 사용자에게 표시해야합니다. 저는 지원팀에서 일하며 프로그래머가 프로그램에서 무슨 일이 일어 났는지 말할 수 없다는 것을 매일 봅니다.
데몬 스레드가있는 경우 종료되는 것을 방지해야합니다. 다른 경우에는 응용 프로그램이 올바르게 작동합니다.
java.lang.Error
최고 수준 에서만 잡을 수 있습니다.
오류 목록을 보면 대부분 처리 할 수 있음을 알 수 있습니다. 예를 들어 a ZipError
는 손상된 zip 파일을 읽을 때 발생합니다.
가장 일반적인 오류는 OutOfMemoryError
및이며 NoClassDefFoundError
, 대부분의 경우 런타임 문제입니다.
예를 들면 :
int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];
생성 할 수 OutOfMemoryError
있지만 런타임 문제이며 프로그램을 종료 할 이유가 없습니다.
NoClassDefFoundError
라이브러리가 없거나 다른 Java 버전으로 작업하는 경우 대부분 발생합니다. 프로그램의 선택적 부분 인 경우 프로그램을 종료해서는 안됩니다.
Throwable
최상위 수준에서 포착 하고 유용한 오류 메시지를 생성하는 것이 좋은 생각 인 이유에 대한 더 많은 예를 제공 할 수 있습니다 .
OutOfMemoryError
런타임 오류가 아닙니다. 애플리케이션이 복구 할 수 있다는 보장이 없습니다. 운이 좋으면 OOM을 가져올 수 new byte[largeNumber]
있지만 할당이 OOM을 유발하기에 충분하지 않은 경우 다음 줄 또는 다음 스레드에서 트리거 될 수 있습니다. length
신뢰할 수없는 입력 인 경우을 호출하기 전에 유효성을 검사해야 하므로 런타임 문제 new byte[]
입니다.
NoClassDefFoundError
컴파일 된 자바 코드가 클래스를 찾을 수 없을 때 호출되므로 어디서나 발생할 수 있습니다 . JDK가 잘못 구성되면 java.util.*
클래스 사용 시도가 트리거 될 수 있으며 이에 대해 프로그래밍하는 것은 사실상 불가능합니다. 선택적으로 종속성을 포함하는 경우을 사용 ClassLoader
하여 존재하는지 확인 해야합니다 ClassNotFoundException
.
ZipError
클래스가 포함 된 jar 파일이 손상된 zip 파일임을 나타냅니다. 이것은 매우 심각한 문제이며이 시점에서 실행되는 코드를 신뢰할 수 없으며 그로부터 "복구"를 시도하는 것은 무책임한 일입니다.
java.lang.Error
또는 java.lang.Throwable
최상위 수준과 그것으로 뭔가를 시도 - 오류 메시지를 기록 말한다. 그러나 그 시점에서 이것이 실행될 것이라는 보장은 없습니다. JVM이 OOMing 인 경우 로그를 시도하면 더 많은을 할당하여 String
다른 OOM을 트리거 할 수 있습니다 .
다중 스레드 환경에서 가장 자주 포착하고 싶어합니다! 당신이 그것을 잡으면 그것을 기록하고 전체 응용 프로그램을 종료하십시오! 그렇게하지 않으면 중요한 부분을 수행 할 수있는 일부 스레드가 죽고 나머지 응용 프로그램은 모든 것이 정상이라고 생각합니다. 그 중에서 원하지 않는 상황이 많이 발생할 수 있습니다. 가장 작은 문제 중 하나는 다른 스레드가 하나의 스레드가 작동하지 않아 일부 예외를 던지기 시작하면 문제의 원인을 쉽게 찾을 수 없다는 것입니다.
예를 들어, 일반적으로 루프는 다음과 같아야합니다.
try {
while (shouldRun()) {
doSomething();
}
}
catch (Throwable t) {
log(t);
stop();
System.exit(1);
}
어떤 경우에도 다른 오류를 다르게 처리하기를 원할 것입니다. 예를 들어 OutOfMemoryError에서는 애플리케이션을 정기적으로 닫을 수 있고 (일부 메모리를 확보하고 계속할 수도 있음) 다른 일부에서는 수행 할 수있는 작업이 많지 않습니다.
는 Error
발생하지 않아야하는 비정상적인 상태를 나타내 므로 일반적으로 잡히면 안됩니다. .
Error
클래스에 대한 Java API 사양에서 :
An
Error
은Throwable
합리적인 응용 프로그램이 포착하려고하지 않아야하는 심각한 문제를 나타내는 의 하위 클래스입니다 . 이러한 오류는 대부분 비정상 상태입니다. [...]메서드는 throws 절에서 메서드 실행 중에 throw 될 수 있지만 포착되지 않은 Error의 하위 클래스를 선언 할 필요가 없습니다. 이러한 오류는 발생해서는 안되는 비정상적인 조건이기 때문입니다.
사양에서 언급했듯이 Error
는 가능성이있는 상황에서만 발생하며, Error
발생시 응용 프로그램이 수행 할 수있는 작업이 거의 없으며 일부 상황에서는 Java Virtual Machine 자체가 불안정한 상태 (예 :VirtualMachineError
)
an Error
은 절에 Throwable
의해 잡힐 수 있음을 의미 하는 하위 클래스 try-catch
이지만 응용 프로그램이 비정상 상태에있을 때 실제로 필요하지는 않습니다.Error
JVM에 의해 발생합니다.
Section 11.5 The Exception Hierarchy of the Java Language Specification, 2nd Edition 에도이 주제에 대한 짧은 섹션이 있습니다.
그리고 오류를 발견하면 다시 던져야 하는 몇 가지 다른 경우가 있습니다 . 예를 들어 ThreadDeath 는 절대 잡히지 않아야합니다. 포함 된 환경 (예 : 응용 프로그램 서버)에서 잡으면 큰 문제가 발생할 수 있습니다.
응용 프로그램은 비동기 적으로 종료 된 후 정리해야하는 경우에만이 클래스의 인스턴스를 포착해야합니다. ThreadDeath가 메서드에 의해 잡히면 스레드가 실제로 죽도록 다시 throw되는 것이 중요합니다.
Error
.
아주 드물게.
나는 아주 특정한 한 가지 알려진 경우에만 그것을했다. 예를 들어, 두 개의 독립 ClassLoader가 동일한 DLL을로드하는 경우 java.lang.UnsatisfiedLinkError가 발생할 수 있습니다 . (JAR를 공유 클래스 로더로 이동해야한다는 데 동의합니다)
그러나 가장 일반적인 경우는 사용자가 불만을 제기했을 때 무슨 일이 일어 났는지 알기 위해 로깅이 필요하다는 것입니다. 사용자에게 메시지 나 팝업이 표시되기를 원합니다.
C / C ++의 프로그래머조차도 오류를 표시하고 종료하기 전에 사람들이 이해하지 못하는 것을 알려줍니다 (예 : 메모리 오류).
Android 애플리케이션에서 java.lang.VerifyError를 포착하고 있습니다 . 내가 사용중인 라이브러리는 이전 버전의 OS가 설치된 장치에서 작동하지 않으며 라이브러리 코드에서 이러한 오류가 발생합니다. 물론 런타임에 OS 버전을 확인하여 오류를 피할 수 있지만 :
테스트 환경에서 java.lang.AssertionError를 잡는 것은 매우 편리합니다 ...
이상적으로는 오류를 처리 / 캐치하지 않아야합니다. 그러나 프레임 워크 나 응용 프로그램의 요구 사항에 따라해야 할 경우가있을 수 있습니다. 더 많은 메모리를 소비 하는 DOM 파서 를 구현하는 XML 파서 데몬이 있다고 가정 해 보겠습니다 . Parser 쓰레드가 OutOfMemoryError를 받았을 때 죽지 말아야한다는 요구 사항이 있다면 , 대신 그것을 처리하고 애플리케이션 / 프레임 워크 관리자에게 메시지 / 메일을 보내야합니다.