본문 바로가기

JAVA

[Java] 에러, 예외 정리하기

반응형

우리가 코드를 실행하는데 예기치 않은 문제로 인해서 정상적인 실행이 아니라 프로그램이 비정상적으로 종료가 될 수 있다. 이러한 결과의 원인이 나타나는 이유는 에러(error)나 예외(Exception)가 될 수 있다.

오늘은 프로그램을 비정상적으로 종료시키는 에러와 예외에 대해 알아보겠다.

1. 에러 (Compile Error, Runtime Error, Logical Error)

에러는 발생 시점에 따라서 컴파일 에러(compile error), 런타임 에러 (runtime error)로 나눌 수 있다. 

우선 컴파일 에러에 대해서 먼저 알아보자.

우리가 Java, C, Python 등으로 코딩을 했다고 하더라도 컴퓨터는 이것을 읽지 못 한다. 컴퓨터는 0,1로 이루어진 언어만 이해할 수 있기 때문에 우리가 코딩한 것들을 컴퓨터가 이해할 수 있도록 변환하는 것을 컴파일이라고 한다.

이때 컴파일을 해주는 것이 컴파일러인데 컴파일러는 소스코드를 쭉 훑으면서 오타, 잘못된 문법, 자료형 체크 등 검사를 하며 에러가 있는지 없는지 확인한다.

다음은 런타임 에러이다.

런타임 에러는 컴파일 검사를 끝내고 실행을 하는 도중에 발생하는 에러이다. 예시로는 배열 인덱스 초과, 0으로 나누기, 메모리 초과 등이 있다

그리고 논리적 에러(logical error)라는 것이 있는데 이것은 우리가 코딩을 하고 실행을 했는데 우리의 기대와 다른 결과가 나오는 경우이다. 예를 들어서 게임 캐릭터가 피가 0인데 죽지 않는 경우, 비행기의 크기가 음수가 되는 경우 등이 있다.

2. 예외 (Exception)

 

출처 : 인프런 - 스프링 DB 1편 (김영한)

 

예외는 우선 체크 예외, 언체크 예외로 구분된다. 이름이 체크, 언체크인 이유는 체크 예외는 모두 컴파일러가 체크하는 예외이고 언체크 예외는 컴파일러가 체크하지 않는 예외이다.

 

1. 체크 예외

체크 예외는 예외를 잡아서 처리하거나 던지거나 둘 중 하나를 필수로 해야 한다.

public class Practice2 {
    public static void main(String[] args) throws IOException {
     //   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

            Solve solve = new Solve();

        try {
            solve.call();
        } catch (CheckedException e) {
            System.out.println("예외 처리 : " + e.getMessage());
        }

    }

    // Exception을 상속받으면 체크 예외가 된다.
    static class CheckedException extends Exception {
        public CheckedException(String message) {
            super(message);
        }

    }

    static class Solve {
        public void call() throws CheckedException {
            throw new CheckedException("ex");
        }
    }
}

 

 Solve 클래스에서 call() 뒤에 throws checkedException을 빼면 

Unhandled exception 이라는 에러가 뜬다. 이것은 컴파일러가 너는 지금 예외를 다루고 있지 않는다고 경고를 하는 것이다. 위에 말한 것처럼 체크 예외는 예외를 try catch로 처리하거나 던져야 하는데 여기서 예외를 던진다고 throw new CheckedException을 했는데 컴파일러가 확인할 수 없도록 throws를 빼서 컴파일러가 미리 알려준 것이다.

 

체크 예외의 장단점

장점 : 컴파일러가 미리 예외를 처리하거나 던지라고 알려주는 것이 큰 장점이다.

단점 : 컴파일러가 다 잡아주다보니 체크 예외가 있으면 모든 예외를 잡거나 던지도록 처리해줘야 한다.

 

2. 언체크 예외

언체크 예외는 RuntimeException과 그 하위 예외들을 일컫는다.

체크 예외와 달리 컴파일러가 예외를 체크하지 않아서 예외를 던지는 throws를 생략할 수 있다.

생략한다고 예외를 안 던지는 것은 아니고 자동으로 던지도록 설정이 되어있다.

 

public class Practice2 {
    public static void main(String[] args) throws IOException {
     //   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

            Solve solve = new Solve();

        try {
            solve.call();
        } catch (UnCheckedException e) {
            System.out.println("예외 처리 : " + e.getMessage());
        }

    }

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

    }

    static class Solve {
        public void call()  {
            throw new UnCheckedException("ex");
        }
    }
}

 체크 예외와 다른 점은 solve 클래스에서 throws 선언 차이이다.

 

언체크 예외의 장단점

장점 : 컴파일러가 예외를 체크 안 하다보니 신경쓰고 싶지 않은 언체크 예외는 무시할 수 있다.

단점 : 예외를 무시한다는 것은 곧 어쩌다가 예외를 누락하는 경우를 불러올 수 있다.

 

반응형

'JAVA' 카테고리의 다른 글

[JAVA] Map.Entry를 이용한 HashMap 정렬  (1) 2025.01.23