목차

1. 예외 계층 

2. 예외 기본 규칙

3. 체크 예외

4. 언체크 예외 (런타임 예외)


1. 예외 계층

예외 처리는 아래 키워드를 사용한다

try, catch, finally, throw, thorws

  • Obejct: 자바에서 기본형을 제외한 모든 것은 객체다. 예외의 최상위 부모도 Object 다.
  • Throwable: 최상위 예외 객체다. 하위에 Exception 과 Error 가 있다.
  • Error: 메모리 부족이나 심각한 시스템 오류와 같은 애플리케이션에서 복구 불가능한 시스템 예외다.
    • 애플리케이션 개발자는 이를 잡으려고 해선 안 된다.
  • Exception
    • 애플리케이션 로직에서 사용할 수 있는 최상위 예외다.
  • 체크 예외
    • RuntimeException 을 제외하고는 모두 컴파일러가 체크하는 예외다
    • 개발자가 체크 예외를 처리하지 않으면 컴파일 오류가 발생한다.
  • 언체크 예외 (런타임 예외)
    • 컴파일러가 체크하지 않는다.
    • RuntimeException 과 그 자식 예외는 모두 언체크 예외다

주의

  • 상속 관계에서 부모 타입은 자식을 담을 수 있다. 이 개념이 예외 객체에서도 적용된다.
    • 상위 예외를 catch 로 잡으면, 하위 예외 까지 함께 잡는다.
  • 따라서 애플리케이션 로직에서는 Throwable 예외를 잡으면 안된다. 애플리케이션 개발자가 잡으면 안 되는 Error 예외 까지 같이 잡을 수 있기 때문이다.
  • 이런 이유로 애플리케이션 로직에서는Exception 부터 ‘처리가 필요한 예외’로 여기고 잡으면 된다.

 

2. [중요] 예외 기본 규칙

예외는 폭탄 돌리기와 같다. 잡아서 밖으로 던지거나, 처리하거나.
  • 예외를 처리하지 못하면, 자신을 호출한 곳으로 예외를 던져야 한다.
  • 예외를 잡거나 던질 때, 지정한 예외 뿐만 아니라 그 예외의 자식 예외도 함께 처리할 수 있다!
  • 예외를 처리하지 못하고 계속 던지면 어떻게 될까?
    • 자바 main() 밖으로 예외로 던지면, 예외 로그를 출력하면서 시스템이 종료된다.

 

3. 체크 예외

  • Exception 과 그 하위 예외 모두는 컴파일러가 체크하는 체크 예외다.
    • RuntimeException 은 제외다. 언체크 예외다.
  • 체크 예외는 잡아서 처리하거나, 자신을 호출한 곳으로 던져야 한다. 그렇지 않으면 컴파일 오류가 발생한다.

 

Exception 을 상속받은 예외는 체크 예외가 된다.

  • MyCheckedException 예외 클래스를 만들자.
    • Exception 을 상속받으면 된다.
public class MyCheckedException extends Exception {
    public MyCheckedException(String message) {
        super(message);
    }
}
  • super(message)
    • Exception 에는 message 를 보관하는 생성자가 있다.
    • Throwable 의 detailMessage 에 저장된다.
  • 보관한 message 를 꺼내려면, Throwable 에서 제공하는 getMessage() 메서드로 꺼낸다

 

throw VS throws 헷갈리지 말기

  • throws : 예외를 메서드 밖으로 던질 때 쓰는 키워드다
  • throw : 예외를 발생시킨다.
    • new 로 객체를 생성하고 예외를 발생시킬 수 있다
    • throw new MyCheckedException(”msg”)

 

Client class : 예외 발생하면 밖으로 던지기

  • call() throws MyCheckedException → MyCheckedException 가 발생하면 메서드 밖으로 던진다
  • throw new MyCheckedException("ex") → 예외 객체를 생성하여 예외를 발생시킨다.
public class Client {
  
  public void call() throws MyCheckedException { // throws 예외 던지기 

      // throw 예외 발생 
      throw new MyCheckedException("ex");
  }
}

 

 

예외를 잡아서 처리하기

  • try catch 를 사용해서 예외를 잡으면 된다.
  • client.call() 호출하면, MyCheckedException 이 발생하여 예외 객체가 넘어온다.
  • catch 블럭 내에 예외 처리 로직을 작성한다.
public void callCatch() {

  try {
      client.call();
  } catch (MyCheckedException e) { // 예외 처리 로직
      
      System.out.println("예외 처리, message=" + e.getMessage());
      // 예외 처리 후, 정상 흐름으로 간다.
  }

  System.out.println("정상 흐름");
}

catch 의 대상에 없는 예외라면?

  • try 에서 잡은 예외가 catch 의 대상에 없으면 예외를 잡을 수 없다. 이때는 예외를 밖으로 던져야 한다.
  • catch 대상을 RuntimeException 으로 바꿔보면, 컴파일 에러가 발생한다!
    • unreported exception: exception.basic.checked.MyCheckedException;
    • must be caught or declared to be thrown → 잡거나 던진다고 선언하세요.

 

그 예외의 자식 예외도 함께 처리하기

  • MyCheckedException 은 Exception 을 상속 받은 체크 예외 클래스다.
  • catch 대상을 MyCheckedException 대신 Exception 으로 바꿔서 실행해보자.
public void callCatch() {

    try {
        client.call();
    } catch (Exception e) { // 예외 처리 로직
        
        System.out.println("예외 처리, message=" + e.getMessage());
    }

    System.out.println("정상 흐름");
}
  • 실행 해보면, MyCheckedException 예외를 catch 로 잡아서 처리한 것을 확인할 수 있다

 

예외를 메서드 밖으로 던지기 throws

  • client.call() 호출하면, MyCheckedException 이 발생하여 예외 객체가 넘어온다.
  • 여기서는 메서드에 선언한 throws 로 예외를 메서드 밖으로 던진다.
  • 체크 예외를 밖으로 던지려면, throws 예외를 메서드에 필수로 지정해야 한다.
public void catchThrow() throws MyCheckedException {
    client.call();
}

정리

  • 체크 예외는 개발자가 명시적으로 처리해야 한다. 처리 안하면, 컴파일 오류 난다.
  • try-catch 로 잡아서 처리 하거나, 메서드에 throws 를 지정해서 예외를 밖으로 던진다는 선언을 필수로 해야 한다.

 

4. 언체크 예외 (런타임 예외)

  • 컴파일러가 예외를 체크하지 않는다.
  • 언체크 예외는 체크 예외와 기본적으로 동일하다. 한 가지 차이가 있다. throws 를 생략할 수 있다.
  • throws 를 생략해도, 자동으로 예외를 밖으로 던진다.

체크 예외 VS 언체크 예외

  • 체크 예외: 예외를 처리하지 않는 경우, throws 로 던져야만 컴파일 오류가 안 난다.
  • 언체크 예외: throws 를 생략해도, 자동으로 예외를 밖으로 던진다.

 

언체크 예외 예제코드

  • 언체크 예외 클래스 RuntimeException 을 상속받은 예외는 언체크 예외가 된다.
public class MyUncheckedException extends RuntimeException{
    public MyUncheckedException(String message) {
        super(message);
    }
}
  • 언체크 예외를 발생시키는 Client 클래스
    • 체크 예외와는 다르게, 메서드에 throws 키워드를 생략했다.
public class Client {

    public void call() { // 메서드에 throws 키워드 생략 
        throw new MyUncheckedException("unckecked exception! ");
    }
}
  • Client 클래스 메서드를 호출하는 Service 클래스
public class Service {
    Client client = new Client();

    public void callCatch() { // 필요한 경우, 예외를 잡아서 처리할 수 있다.
        
        try {
            client.call();
        } catch (MyUncheckedException e) {
            System.out.println("예외 처리, message: " + e.getMessage());
        }
        System.out.println("정상 로직");
    }
    
    /** 
     * 예외를 잡지 않아도 컴파일 에러가 안나고, 상위로 올라간다. 
     * */
    public void callThrow() {
        client.call();
    }
}
  • 예외 잡아서 처리하는 메서드 callCatch() 호출하여 실행
public class UncheckedCatchMain {
    public static void main(String[] args) {
        Service uncheckedService = new Service();
        uncheckedService.callCatch();
        System.out.println("정상 종료");
    }
}
  • 실행 결과
예외 처리, message: my unckecked exception! 
정상 로직
정상 종료
  • 예외를 호출부로 던지는 callThrow() 메서드를 호출하여 실행
public class UncheckedCatchMain {
    public static void main(String[] args) {
        Service uncheckedService = new Service();
        uncheckedService.callThrow();
        System.out.println("정상 종료");
    }
}
  • 실행 결과
    • callThrow() 메서드에 throws 키워드가 없어도, 컴파일 오류가 나지 않는다.
    • callThrow() 메서드가 실행 되었고, callThrow() 에서 예외를 잡아서 처리하지 않았기 때문에 main() 으로 언체크 예외가 넘어왔다.
    • main() 에서도 MyUncheckedException 을 처리하지 않고 있어서 main() 도 예외를 밖으로 던진다.
    • callThrow() 까지만 실행 됬으니까, 다음 줄에 있는 “정상 종료” 출력이 실행되지 않는다.
    • 이렇게 되면 예외 정보와 스택 트레이스가 출력되면서 프로그램이 종료된다.
Exception in thread "main" exception.basic.unchecked.MyUncheckedException: my unckecked exception! 
	at exception.basic.unchecked.Client.call(Client.java:6)
	at exception.basic.unchecked.Service.callThrow(Service.java:23)
	at exception.basic.unchecked.UncheckedCatchMain.main(UncheckedCatchMain.java:7)

정리

  • 신경쓰고 싶지 않은 언체크 예외를 무시할 수 있다는 장점이 있다. throws 예외를 생략 가능!
  • 하지만, 컴파일러를 통해 예외 누락을 잡을 수는 없다.
  • 현대 애플리케이션에서는 체크 예외를 거의 쓰지 않는다.

인프런 김영한 자바 중급1 강의를 듣고 요약한 내용입니다. 

728x90

'프로그래밍 > JAVA' 카테고리의 다른 글

List  (0) 2025.03.28
스레드 생성하기  (0) 2025.03.28
String 클래스  (1) 2025.03.20
자바 객체 지향  (0) 2025.03.13
자바 기본1  (0) 2025.03.13

+ Recent posts