예외(Exception) 이란 ?
프로그램 실행 중에 발생할 수 있는 문제를 나타내는 것으로, 일반적으로 예상하지 못한 상황이나 오류 상황을 의미한다. 예외 처리는 이러한 예외 상황이 발생했을 때 프로그램이 비정상적으로 종료되는 것을 방지하고, 예외 상황을 안전하게 처리하여 프로그램의 정상적인 흐름을 유지할 수 있도록 하는 중요한 기능이다.
Exception(예외) 과 Error(오류) 의 차이점
예외 처리에 대해 공부하기 전에 프로그램 오류에 관해 먼저 알아야 한다. Exception (예외) 와 Error (오류) 는 모두 Throwable 클래스를 상속 받고 있지만, 용도와 사용 방법에는 아주 큰 차이가 있다. Exception 은 프로그램 코드에 의해 일반적인 흐름을 방해할 수 있지만, 적절히 처리를 할 수 있고 복구가 가능한 다소 미약한 오류이다. 반면 Error 는 프로그램 코드에 의해 수습될 수 없는 심각한 오류를 뜻한다. 실제로 Java Documentation 을 확인해보면 Exception 과 Error 는 다르다고 가지를 쳐 놓은것을 확인할 수 있다.
Exception | https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/Exception.html |
Error | https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/Error.html |
쉽게 말하자면, 예외의 경우 코드 적으로 처리가 가능하기 때문에 개발자가 핸들링 할 수 있지만, 오류의 경우는 프로그램 자체의 문제이기 때문에 개발자가 핸들링 할 수 없는 것이다. Error 의 경우에는 메모리 부족 (OutOfMemoryError) 이나 스택오버플로우 (StackOverFlowError) 를 예로 들 수 있으며 JVM 실행에 문제가 생긴 것이다.
오류의 종류
오류에 종류에는 크게 3가지가 있다.
오류 | 설명 | 종류 |
컴파일 에러 (compile-time error) | 컴파일 시에 발생하는 에러 | FileNotFoundException ClassNotFoundException |
런타임 에러 (runtime error) | 실행시 발생하는 에러 | NullPointException ArrayIndexOutOfBoundsException |
논리적 에러 (logical error) | 실행은 되지만, 의도와 다르게 동작하는 것 |
컴파일 에러 (Compile-time error)
컴파일 에러는 컴파일 단계에서 오류를 발견하면 컴파일러가 에러를 출력해주는 것을 말한다. 컴파일 에러의 대표적인 원인으로는 문법 구문 오류(Syntax Error) 를 들 수 있으며, 오탈자, 맞춤법, 문장부호(;), 선언되지 않은 변수 사용 등이 이에 해당한다. 아래의 예제 코드는 CompileError 라는 변수를 선언하지 않고 사용하였을 때 나타난 오류이다. 이와 같은 오류가 컴파일 에러에 해당하며, 컴파일 에러가 있다는 것은 곧 컴파일이 안된다는 의미이며, 이는 프로그램이 만들어지지 않아 프로그램 실행 자체가 불가능 함을 알려준다.
javac.exe 는 Java 소스 코드를 컴파일 하는 Java 컴파일러의 실행 파일이다. 이 컴파일러는 코드를 분석하고, 구문 오류나 타입 불일치 같은 컴파일 에러를 찾아내며, 에러가 있으면 해당 에러 메세지를 출력한다. 이 과정은 명령줄 환경에서 수동으로 진행된다. 반면, 대부분의 IDE는 코드를 작성하는 동안 주기적으로, 자동으로 컴파일을 수행한다. 따라서 개발자가 문제를 쉽게 인식하고 수정할 수 있게 도와준다. (실시간으로 빨간색 밑줄이 쳐지는 이유도 이에 해당 ! )
런타임 에러(Runtime error)
런타임 에러는 컴파일에는 문제가 없더라도, 프로그램 실행 중에 에러가 발생해서 잘못된 결과를 얻을 경우 생기는 에러이다. 컴파일러가 소스코드의 기본적인 사항을 컴파일 시에 모두 걸러 줄 수 있지만, 실행도중에 발생 할 수 있는 잠재적인 오류까지는 검사할 수 없기 때문에 실행 도중 비정상적으로 종료 되거나 실행될 경우 나타나는 에러이다. 아래의 예제 코드는 while 문의 조건이 잘못 설정되어 조건이 항상 참으로 평가되어 반목문이 종료되지 않음을 보여준다. 이것을 우리는 무한 루프라고 표현하며 사용자가 강제로 프로그램을 종요시키지 않는 이상 계속해서 실행 상태에 머물게 된다.
논리적 에러(Logical error)
논리적 에러는 프로그램의 실행 흐름이나 알고리즘이 잘못되어 예상과 다른 결과가 나오는 에러이다. 이러한 에러는 컴파일러나 인터프리터가 감지하지 못하여 생기는 에러이며, 주로 개발자의 실수로 인해 발생한다. 즉, 정상 작동은 되어지나 개발자의 의도대로 흘러가지 않는 것을 뜻한다. 이러한 에러를 보통 '버그' 라고 부르며, 게임 캐릭터의 체력이 0 이 되었는데도 죽지 않는다던가, 재고량이 음수가 나오면 안되는데 음수가 나오는 경우를 예로 들 수 있다. 아래의 예제 코드는 정수 배열의 요소를 합산하는 코드를 작성하려고 하였으나, 실수로 곱셈 연산자를 사용하였을 경우의 논리적 에러를 보여준다.
그렇다면, 예외 처리(Exception handling)이란 ?
프로그램 실행시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 행위를 말한다. 프로그램 실행 도중에 발생하는 에러는 어쩔 수 없지만, 예외가 발생하더라도 프로그래머가 이에 대한 적절한 코드를 미리 작성해 놓음으로써 어느정도 프로그램의 비정상적인 종료 혹은 동작을 방지할 수 있다. 따라서 예외 처리의 궁극적인 목적은 예외의 발생으로 인한 실행 중인 프로그램의 갑작스런 비정상적인 종료를 막고, 정상적인 실행상태를 유지하는 것이다.
예외 클래스의 계층 구조
자바에서는 실행 시 발생할 수 있는 오류를 클래스로 정의하였다. Java Documentation 에서 Execption 을 검색하면 엄청난 종류의 Exception 을 확인 할 수 있는데 그 중 우리에게 익숙한 NullPointerException 과 IOException 도 모두 클래스에 포함되어 있는것을 확인할 수 있다. 모든 예외의 최고 조상은 Exception 클래스이며, Exception 클래스는 Throwable 에 상속되어있는 것을 확인할 수 있다. Throwable 클래스의 역할은 오류나 예외에 대한 메시지를 담아준다. 대표적으로 getMessage() 와 printStackTrace() 가 있다. Throwable 의 상속 계층도를 도식화하면 다음과 같다.
위와 같은 계층도에서 볼 수 있듯이 자바에서 다루는 모든 예외 오류는 Exception 클래스에서 처리하는 것을 확인 할 수 있으며, 앞서 얘기 했듯이 컴파일 에러와 런타임 에러를 따로 클래스에서 구분한 것을 확인 할 수 있다. RuntimeException 은 말 그대로 런타임시에 발생하는 예외이고, 그 외에 다른 Exception 은 컴파일 에러라고 보면 된다. 아래의 도식화는 한눈에 알아보기 쉽게 간단하게 표현한 것으로 더 많은 종류의 Exception 이 있다 !
'Java' 카테고리의 다른 글
[Java] 예외처리하기(try-catch-finally) (0) | 2024.05.15 |
---|---|
[Java] 에노테이션 (Annotation) - 수정 (0) | 2024.05.10 |
[Java] 내부 클래스(Inner class) (0) | 2024.05.01 |
[Java] 인터페이스(Interface) (0) | 2024.04.29 |
[Java] 추상화(Abstract) (2) | 2024.04.28 |