체크 예외의 재정의

Yumin Jung·2024년 11월 18일
0

ABOUT 프로그래밍

목록 보기
13/15

Java에서 Thread.sleep()과 체크 예외

개발을 하다 보면 Thread.sleep()을 사용할 때 체크 예외(Checked Exception)로 인해 코드를 작성하면서 당황했던 경험이 있을 수 있다. 이 글에서는 체크 예외와 Thread.sleep()의 관계, 그리고 main 메서드에서 예외가 동작하는 방식을 살펴보겠다.


1. Thread.sleep()의 기본 개념

Thread.sleep() 메서드는 현재 실행 중인 스레드를 일정 시간 동안 대기 상태로 만드는 역할을 한다. 다음은 간단한 예시이다:

public class SleepExample {
    public static void main(String[] args) {
        try {
            System.out.println("Start");
            Thread.sleep(1000);  // 1초 동안 스레드 멈춤
            System.out.println("End");
        } catch (InterruptedException e) {
            System.out.println("Thread was interrupted!");
        }
    }
}
  • Thread.sleep(1000): 현재 스레드를 1초(1000ms) 동안 멈춘다.
  • InterruptedException: 이 메서드는 체크 예외InterruptedException을 던질 수 있다. 이는 try-catch 블록으로 처리하거나, 메서드 선언에 throws로 명시해야 한다.

2. 체크 예외란 무엇인가?

체크 예외(Checked Exception)컴파일러가 강제하는 예외이다. 즉, 예외 처리를 반드시 해야만 컴파일이 성공한다. 대표적인 예로 IOException, SQLException, 그리고 InterruptedException 등이 있다.

체크 예외 처리 방식

  1. try-catch로 예외 처리:

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        System.out.println("Thread interrupted!");
    }
  2. throws 키워드로 예외 던지기:

    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(1000);
    }

3. 부모-자식 클래스와 체크 예외

자바의 상속에서 체크 예외는 특정 규칙을 따른다. 부모 클래스의 메서드가 예외를 던지지 않으면, 이를 재정의(override)하는 자식 클래스의 메서드에서도 체크 예외를 던질 수 없다.

예제:

class Parent {
    public void doSomething() {
        // 예외를 던지지 않음
    }
}

class Child extends Parent {
    @Override
    public void doSomething() throws InterruptedException {  // 컴파일 에러 발생!
        Thread.sleep(1000);
    }
}
  • 오류 원인:
    • 부모의 doSomething() 메서드는 예외를 던지지 않으므로, 자식 클래스도 예외를 던질 수 없다.
    • 이는 리스코프 치환 원칙(Liskov Substitution Principle)에 따라, 자식 클래스가 부모 클래스의 행동을 대체할 수 있어야 하기 때문이다.

4. main 메서드에서는 왜 예외를 던질 수 있을까?

main 메서드JVM이 직접 호출하는 프로그램의 진입점이다. 따라서 예외 처리를 위해 호출될 상위 메서드가 없으며, 예외가 발생하면 JVM이 직접 처리한다.

예제: throws 선언

public class MainExample {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(1000);  // 예외를 JVM이 처리
        System.out.println("Program continues...");
    }
}
  • throws로 예외 선언: main 메서드에서 발생한 체크 예외는 JVM이 받아들여 프로그램이 종료되거나 로그로 기록된다.

결과:

만약 예외가 발생하면, 스택 트레이스와 함께 예외 정보가 출력된다.


5. Thread.sleep()와 체크 예외의 실무 활용

체크 예외는 예외 처리를 강제함으로써 개발자가 예외 상황을 명확히 인지하고 적절히 대응하도록 돕는다. 그러나 때로는 이런 예외 처리 규칙이 번거로울 수 있다.

  • 일반적인 패턴:

    public void pauseThread(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            // 예외 발생 시 스레드 상태 복구 또는 로깅
            Thread.currentThread().interrupt();  // 스레드 인터럽트 상태 복구
            System.out.println("Sleep was interrupted");
        }
    }
  • 스레드 인터럽트 처리:
    예외가 발생하면 스레드의 인터럽트 상태를 복구하여 정상적인 처리를 이어가는 것이 중요하다.


6. 결론

  • Thread.sleep()체크 예외를 던지기 때문에 반드시 try-catch 또는 throws로 예외를 처리해야 한다.
  • 부모 클래스에서 예외를 던지지 않는다면, 자식 메서드도 예외를 던질 수 없다.
  • main 메서드는 프로그램의 진입점으로 JVM이 호출하며, 체크 예외를 자유롭게 던질 수 있다.

0개의 댓글

관련 채용 정보