Java 언어에서 예외는 두 가지 범주로 나뉩니다.
확인된 예외: 이 유형의 예외는 throws 절에서 명시적으로 발생하거나 메서드 내에서 포착되어야 합니다. 예를 들어 IOException 또는 ClassNotFoundException이 있습니다.
확인되지 않은 예외: 이 유형의 예외는 명시적으로 발생하거나 포착될 필요가 없습니다. 예를 들어 NumberFormatException입니다.
Thread 객체의 run() 메소드에서 확인된 예외가 발생하면 run() 메소드는 예외를 발생시킬 수 없기 때문에 이를 포착하고 처리해야 합니다. Thread 객체의 run() 메서드에서 확인되지 않은 예외가 발생하면 기본 동작은 콘솔에 스택 추적 정보를 인쇄한 다음 프로그램을 종료하는 것입니다.
다행스럽게도 Java는 프로그램 종료를 방지하기 위해 Thread 객체에서 발생한 확인되지 않은 예외를 처리하도록 특별히 설계된 메커니즘을 제공합니다.
이 섹션에서는 예를 사용하여 이 메커니즘을 보여줍니다.
알아요
예제를 구현하려면 아래 단계를 따르세요.
1. 먼저 확인되지 않은 예외를 처리하기 위한 클래스를 구현해야 합니다. 이 클래스는 UncaughtExceptionHandler 클래스를 구현하고 이 인터페이스에 선언된 uncaughtException() 메서드를 구현해야 합니다. 이 예제에서 클래스 이름은 ExceptionHandler이고 uncaughtException() 메서드는 예외와 예외를 발생시킨 스레드 정보를 출력합니다. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
공용 클래스 ExceptionHandler는 Thread.UncaughtExceptionHandler를 구현합니다.
@보수
공공 무효 uncaughtException(스레드 t, Throwable e) {
System.out.printf("예외가 캡처되었습니다//n");
System.out.printf("스레드: %s/n", t.getId());
System.out.printf("예외: %s: %s/n", e.getClass().getName(),
e.getMessage());
System.out.printf("스택 추적: /n");
e.printStackTrace(System.out);
System.out.printf("스레드 상태: %s/n", t.getState());
}
}
2. 확인되지 않은 예외를 발생시킬 수 있는 Task라는 클래스를 구현하고, Runnable 인터페이스를 구현하고, run() 메서드를 구현하고, 확인되지 않은 예외를 생성할 수 있는 코드 조각을 특별히 코딩합니다(예: 문자열을 숫자로 변환). 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
공개 클래스 작업은 Runnable을 구현합니다.
@보수
공개 무효 실행() {
int numero = Integer.parseInt("diguage.com");
}
}
3. 프로그램의 메인 클래스인 Main 클래스를 생성한 후 main() 메서드를 구현합니다. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
공개 클래스 메인 {
공개 정적 무효 메인(String[] args) {
4. Task 객체를 생성하고 이를 실행하기 위한 Thread 객체를 생성합니다. 확인되지 않은 예외에 대한 처리 클래스를 설정하려면 setUncaughtExceptionHandler() 메서드를 사용하세요. 그런 다음 스레드를 시작하십시오. 코드는 다음과 같습니다:
다음과 같이 코드 코드를 복사합니다.
작업 task = new Task();
스레드 스레드 = 새 스레드(작업);
thread.setUncaughtExceptionHandler(new ExceptionHandler());
thread.start();
5. 예제를 실행하고 결과를 확인합니다.
왜인지 알아
비정상적인 실행 결과는 아래 출력 스니펫에서 확인할 수 있습니다. 예외가 발생한 후 핸들러 클래스에 의해 포착되고 예외 정보가 콘솔에 인쇄됩니다.
다음과 같이 코드 코드를 복사합니다.
예외가 캡처되었습니다.
스레드: 9
예외: java.lang.NumberFormatException: 입력 문자열의 경우: "diguage.com"
스택 추적:
java.lang.NumberFormatException: 입력 문자열의 경우: "diguage.com"
java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)에서
java.lang.Integer.parseInt(Integer.java:492)에서
java.lang.Integer.parseInt(Integer.java:527)에서
com.diguage.books.concurrencycookbook.chapter1.recipe8.Task.run(Task.java:13)에서
java.lang.Thread.run(Thread.java:722)에서
스레드 상태: RUNNABLE
종료 코드 0으로 프로세스가 완료되었습니다.
스레드에서 예외가 발생했는데 해당 예외(여기서는 구체적으로 unchecked 예외를 의미함)가 catch되지 않는 경우 Java 가상 머신은 unchecked 예외 처리 클래스가 설정되어 있는지 여부를 해당 메서드인 uncaughtException() 메서드를 통해 확인합니다. 스레드와 예외를 매개변수로 메서드에 전달합니다.
처리 클래스가 설정되지 않은 경우 JVM(Java Virtual Machine)은 콘솔에 스택 추적 정보를 인쇄한 다음 프로그램을 종료합니다.
끝나지 않는
Thread 클래스에는 확인되지 않은 예외 처리와 관련된 메서드도 있습니다. 이는 프로그램의 모든 스레드에 대해 확인되지 않은 예외 처리 클래스를 설정할 수 있는 정적 메서드 setDefaultUncaughtExceptionHandler()입니다.
스레드에서 포착되지 않은 예외가 발생하면 Java 가상 머신은 세 위치에서 예외 처리 클래스를 찾습니다.
먼저 스레드 개체에서 예외 처리 클래스를 찾으세요. 이것이 바로 이 섹션에서 배운 내용입니다. 존재하지 않는 경우에는 해당 스레드가 위치한 스레드 그룹(ThreadGroup)에서 예외 처리 클래스를 검색한다. 이 부분은 나중에 구체적으로 설명하겠습니다. 여전히 존재하지 않으면 위에서 언급한 프로그램 기본 예외 처리 클래스를 찾으십시오.
위에서 언급한 예외 처리기가 없으면 JVM(Java Virtual Machine)은 예외의 스택 추적 정보를 콘솔에 인쇄한 다음 프로그램을 종료합니다.
교리를 사용하라
이 글은 "Java 7 Concurrency Cookbook"(D Gua Ge가 "Java7 Concurrency 예제 모음"으로 훔쳤습니다)을 번역한 것이며, 학습 자료로만 사용됩니다. 허가 없이 상업적인 목적으로 사용할 수 없습니다.
작은 성공
ExceptionHandler 클래스의 전체 코드는 다음과 같습니다.
패키지 com.diguage.books.concurrencycookbook.chapter1.recipe8;
/**
* 체크되지 않은 예외 처리 클래스
* 날짜: 2013-09-22
* 시간: 23:11
*/
공용 클래스 ExceptionHandler는 Thread.UncaughtExceptionHandler를 구현합니다.
@보수
공공 무효 uncaughtException(스레드 t, Throwable e) {
System.out.printf("예외가 캡처되었습니다/n");
System.out.printf("스레드: %s/n", t.getId());
System.out.printf("예외: %s: %s/n", e.getClass().getName(),
e.getMessage());
System.out.printf("스택 추적: /n");
e.printStackTrace(System.out);
System.out.printf("스레드 상태: %s/n", t.getState());
}
}
Task 클래스의 전체 코드
다음과 같이 코드 코드를 복사합니다.
패키지 com.diguage.books.concurrencycookbook.chapter1.recipe8;
/**
* 예외 발생 클래스
* 날짜: 2013-09-22
* 시간: 23:18
*/
공개 클래스 작업은 Runnable을 구현합니다.
@보수
공개 무효 실행() {
int numero = Integer.parseInt("diguage.com");
}
}
Main 클래스의 전체 코드
다음과 같이 코드 코드를 복사합니다.
패키지 com.diguage.books.concurrencycookbook.chapter1.recipe8;
/**
* 예시의 메인 클래스
* 날짜: 2013-09-22
* 시간: 23:20
*/
공개 클래스 메인 {
공개 정적 무효 메인(String[] args) {
작업 task = new Task();
스레드 스레드 = 새 스레드(작업);
thread.setUncaughtExceptionHandler(new ExceptionHandler());
thread.start();
}
}