본문 바로가기
Java

Java 에서 Exception

by fygoo-826 2025. 2. 4.
728x90
반응형

 예외처리(Exception Handling) 은 프로그래밍에 안정성을 높일 때 가장 중요한 기능이라고 할 수 있다. 이번 포스팅에서는 예외 처리가 왜 필요한지, 자바에서는 어떻게 예외 계층을 관리해주고 있는지, Check Exception 과 Unchecked Exception 에 대해서 설명하고자 한다.


왜 예외 처리가 필요할까?

 예외 처리가 필요한 이유는 I/O 작업과 같이 외부 시스템에 의존하는 작업에서 예상하지 못하는 오류가 발생했을 때, 빠르게 대응하기 위함이다. 예를 들어 네트워크 통신 과정에서 (1) 메시지를 전송 도중 (2) 네트워크 연결 과정에서 등등 실패할 수 있는 상황들이 다양하다.

package exception.ex1;

public class NetworkService {
    public void sendMessage(String data) {
        String address = "http://example.com/";
        NetworkClient client = new NetworkClient(address);

        client.initError(data);
        String connectResult = client.connect();

        if (isError(connectResult)) {
            System.out.println("[네트워크 오류 발생] 오류 코드: " + connectResult);
        } else {
            String sendResult = client.send(data);
            if (isError(sendResult)) {
                System.out.println("[네트워크 오류 발생] 오류 코드: " + sendResult);
            }
        }

        client.disconnect();
    }

    private static boolean isError(String result) {
        return !result.equals("success");
    }
}

 위 코드에서 "connect()" 와 "send()" 의 성공 여부를 확인하고 적절한 오류를 처리하는 방법을 소개해주고 있다. 이렇게 코드를 작성하면 코드가 복잡해지고, 가독성이 떨어지며, 오류 흐름과 정상 흐름이 혼재되어 디버그가 매우 어려운 상황에 놓이게 될 가능성이 높다. 이런 상황에서 예외 클래스를 사용하면 매우 도움이 된다.

 

예외 처리의 장점

 자바 예외 처리 기능을 사용하면 아래와 같은 장점을 확인해볼 수 있다.

  • 정상 흐름과 오류 흐름을 분리해서 코드를 작성할 수 있음
  • 가독성 향상
  • 오류 발생 시, 프로세스의 중단을 막고 클라이언트에게 적절한 응답 코드를 전달해 줄 수 있다

예외 기본 규칙

 자바에서 예외는 객체로 취급되며, 최상위 클래스는 `Throwable`이다. Throwable을 상속하는 두 주요 클래스는 Exception과 Error이다. 일반적으로 개발자는 Error를 처리하지 않으며, Exception 하위에서 체크 예외와 언체크 예외를 구분한다.

예외 기본 규칙

  1. 예외는 잡아서 처리하거나 던져야 한다
  2. 예외를 잡거나 던질 때, 지정한 예외뿐만 아니라 그 예외의 하위 클래스들도 함께 처리할 수 있다

체크 예외 (Checked Exception)
 체크 예외는 Exception을 상속받은 예외를 의미한다. 예를 들어, 커스텀 예외 MyCheckedException을 아래와 같이 정의할 수 있다.

public class MyCheckedException extends Exception {
    public MyCheckedException(String message) {
        super(message);
    }
}

public class Client {
    public void call() throws MyCheckedException {
        throw new MyCheckedException("체크 예외 발생");
    }
}

 여기서 Client.call() 메서드는 throws 키워드를 사용하여 MyCheckedException을 던질 것임을 명시한다. 호출하는 측에서는 이 메서드에서 발생할 수 있는 예외를 처리해야 한다.

체크 예외 처리 예제

public void callWithExceptionHandling() {
    Client client = new Client();
    try {
        client.call();
    } catch (MyCheckedException e) {
        System.out.println("예외 처리 로직: " + e.getMessage());
    }
    System.out.println("정상 흐름");
}

 위와 같이 예외가 발생하면 Catch block 에서 (1) 예외를 밖으로 전달할 지 (2) 바꿔서 던질 지 (3) 무시할 지 결정할 수 있다

 

언체크 예외(Unchecked Exception) 

 언체크 예외는 RuntimeException을 상속받은 예외로, 반드시 처리하거나 throws 키워드를 사용하지 않아도 된다. 예를 들어, NullPointerException과 같은 예외가 언체크 예외의 예시이다.

public void riskyMethod() {
    throw new NullPointerException("널 포인터 예외 발생");
}

public void handleRiskyMethod() {
    try {
        riskyMethod();
    } catch (NullPointerException e) {
        System.out.println("예외 처리 로직: " + e.getMessage());
    }
    System.out.println("정상 흐름");
}

 

 

 실무에서는 체크 예외보다는 언체크 예외를 훨씬 많이 사용한다. 이는 언체크 예외가 개발자의 실수를 줄이는 데 도움이 되고, 예외 처리가 덜 번거롭기 때문이다. 예외 처리에 대한 이해는 프로그램의 안정성과 가독성을 높이는데 기여한다. 항상 적절한 예외 처리를 통해 안전한 코드를 작성하도록 노력해야한다.

728x90
반응형

'Java' 카테고리의 다른 글

Java Thread & Runnable 정리  (0) 2025.02.07
Process & Thread 역할 정리  (0) 2025.02.07
Java 에서 중첩 클래스  (1) 2025.02.03
Java 에서 Time 정리  (0) 2025.02.03
Java 에서 Enum  (1) 2025.02.02