본문 바로가기

java

java Error, Checked Exception, Unchecked Exception - 삽질중인 개발자

반응형

개발을 하다 보면 예외를 처리해야 하는 상황이 아주 많이 발생한다. 이때 예외에 대해서 정확히 알고 있어야 좋은 코드를 짤 수 있기에 예외에 대한 포스팅을 한다.

 

에러(Error) vs 예외(Exception)

우선 자바에서 예외는 크게 Error와 Exception으로 나뉜다.

 

Error란 시스템 레벨에서 발생하는 심각한 수준의 오류를 뜻하며 개발자가 미리 예측하여 처리할 수 없기에 개발 시 예외 처리에 신경 쓰지 않아도 되는 부분이다. 

 

Exception이란 로직 상에서 발생하는 오류로 개발자 구현한 코드에서 발생하여 예외를 예측할 수 있으며 상황에 맞게 처리할 수 있다.

 

 

예외 클래스 구조

이러한 예외 클래스들은 최상위 클래스인 Object를 상속받은 Throwable이라는 클래스를 기반으로 Error와 Exception 클래스로 나뉘며 이때 Exception 클래스는 RuntimeException 상속 여부에 따라 Checked Exception과 Unchecked Exception으로 나뉜다.

 

그래서 예외라고 하면 크게 Error , Checked Exception, Unchecked Exception을 생각하면 된다.

 

 

Checked Exception VS Unchecked Exception

RuntimeException의 상속 여부에 따라 Checked Exception과 Unchecked Exception이 나뉘는데 여러 가지 방면에서 차이가 난다.

 

아래의 표는 Checked Exception과 Unchecked Exception의 차이를 간략하게 표로 정리한 부분이다.

 

  Checked Exception Unchecked Exception
애플리케이션에서
예외 처리 여부
반드시 예외 처리 코드가 있어야 한다. 강제가 아니다.
예외의 확인 서점 컴파일 단계에서부터 컴파일이 되지 않는다. 런타임중 예외가 확인된다.
대표적인 클래스 Exception을 상속 받는 클래스중 RuntimeException을 제외한 모든 예외 클래스
IOException
SQLException
RuntimeException을 상속받는 모든 클래스
NullPointerException
IndexOutOfBoundException

 

예외 처리 방법

Exception을 처리하는 방법은 여러 가지가 있다. 

 

첫 번째로 예외 복구이다.

예외 복구란 예외상황을 파악하고 문제를 해결해서 정상 상태로 돌려놓는 방법 (try - catch - finally) 으로 아래와 같은 코드로 예외를 처리한다.

	public static void main(String[] args) throws IOException {
		byte[] list = {'a', 'b', 'c'};

        try {
            System.out.write(list);
        } catch (IOException e) {
            // 여기서 뭔가를 처리하는 로직을 넣어준다.
        }
    }

이 예외 복구 방법은 대부분의 상황에서 예외를 복구할 수 없기에 실무에서는 보통 잘 사용할 일이 없다.

 

두 번째로는 예외 처리 회피이다.

예외 처리 회피란 예외 처리를 자신이 담당하지 않고 자신을 호출한 쪽으로 던져버리는 방법 ( throws )으로 아래와 같은 코드로 예외를 던져버린다.

public static void main(String[] args) throws IOException {
     byte[] list = {'a', 'b', 'c'};
        
     System.out.write(list[4]);
}

예외 처리 회피의 방법은 적당한 상황에서 사용하면 퀄리티 좋은 코드가 나오지만 무분별하게 사용하게 된다면 코드의 퀄리티가 떨어지기에 추천하는 방법은 아니다.

 

마지막으로는 예외 전환이다.

예외 전환은 예외를 적절한 예외로 전환해서 자신을 호출할 쪽으로 던져버리는 방법으로 아래와 같은 방법으로 예외를 전환시킨다.

    public static void main(String[] args)  {
        byte[] list = {'a', 'b', 'c'};

        try {
            System.out.write(list);
        } catch (IOException e) {
            throw new RuntimeException("list를 읽지 못했습니다.");
        }
    }

 

보통 실무에서는 예외 처리를 하기 위해서 아래와 같은 방법으로 RuntimeException을 상속받은 클래스를 만들어서 예외 전환 방법으로 예외를 처리한다.

public class CustomException extends RuntimeException{
    public CustomException(String message) {
        super(message);
    }
}

 

 

결국 잘 짠 코드는 그냥 로직이 잘 돌아가면 되는 게 아니라 이런 예외 처리에도 하나하나 다 신경써서 만들어진 코드를 말하는것 같다.

 

 


백기선님 유튜브에서 잘못된 부분을 지적해주신 트랜잭션 관련 부분을 삭제했습니다. ( 참고 : https://www.youtube.com/watch?v=_WkMhytqoCc )

 

 

 

 

반응형