Java 예외 처리 개념과 Exception과 Error의 차이점 완벽 정리
🚨 오류인가 예외인가? Java 개발자라면 꼭 알아야 할 핵심 개념!
자바(Java)로 프로그래밍을 하다 보면, 오류 메시지와 함께 프로그램이 멈추는 경험을 하게 됩니다.
이럴 때 “도대체 이게 오류인지 예외인지” 헷갈렸던 적 있으시죠?
또한 try-catch로 뭔가 잡긴 했는데, 왜 잡아야 하는지도 모른 채 복사 붙여넣기만 한 경우도 많을 거예요.
개발이 익숙하지 않은 초보자뿐 아니라, 어느 정도 경력이 있는 분들도 자바의 예외(Exception)와 오류(Error)를 명확히 구분하지 못하는 경우가 많습니다.
이번 글에서는 이 두 개념을 완전히 정리해드릴게요.
처음부터 개념을 정확히 이해하면 실전에서도 당황하지 않고, 안정적인 프로그램을 만들 수 있어요.
그럼 함께 차근차근 살펴보겠습니다 😊
Java에서의 예외 처리(Exception Handling)는 프로그램 안정성과 직결되는 매우 중요한 주제입니다.
이번 글에서는 예외(Exception)와 오류(Error)의 차이점을 중심으로, Java의 예외 처리 구조를 깊이 있게 다룰 예정이에요.
실제 자바에서 발생할 수 있는 예외 상황, 처리 방식, 그리고 컬렉션 등과 연계되는 예외 발생 케이스까지 예제를 통해 쉽게 이해할 수 있도록 설명드릴게요.
프로그래밍 실력을 한 단계 업그레이드할 수 있는 기회가 될 거예요!
📋 목차
🚨 예외와 오류의 차이
Java에서 프로그램 실행 중 발생할 수 있는 문제 상황은 크게 두 가지로 나뉩니다.
바로 오류(Error)와 예외(Exception)입니다.
이 둘은 모두 비정상적인 상황이지만, 의미와 처리 방식에는 분명한 차이가 있어요.
💥 Error는 시스템 자체의 문제
오류(Error)는 JVM의 내부 동작에서 발생하는 치명적인 문제로, 개발자가 직접 처리하기 어렵습니다.
대표적으로 OutOfMemoryError, StackOverflowError 등이 있어요.
이런 오류는 하드웨어 자원 고갈, 재귀 호출 무한 반복 등의 상황에서 발생하며, 대부분 프로그램을 중단시키게 됩니다.
⚠️ 주의: Error는 예외 처리 구문인 try-catch로 포착하거나 복구하려 하지 않는 것이 일반적입니다.
⚠️ Exception은 코드로 처리 가능한 문제
예외(Exception)는 개발자가 예측하고 처리할 수 있는 문제입니다.
파일이 존재하지 않거나, 네트워크 연결이 끊기거나, 배열 인덱스가 잘못 접근된 경우 등이 이에 해당돼요.
이런 예외 상황은 try-catch 문을 통해 적절히 대처할 수 있으며, 프로그램 전체가 중단되지 않도록 설계할 수 있습니다.
💎 핵심 포인트:
Error는 복구가 거의 불가능한 시스템 수준의 문제이고, Exception은 개발자가 코드로 예외 처리를 통해 회복할 수 있는 문제입니다.
| 구분 | Error | Exception |
|---|---|---|
| 정의 | JVM 내부 또는 시스템 수준의 문제 | 개발자가 처리 가능한 프로그램 실행 중 문제 |
| 예시 | OutOfMemoryError, StackOverflowError | FileNotFoundException, NullPointerException |
| 처리 방식 | 처리 불가, 종료 권장 | try-catch 등으로 처리 가능 |
이처럼 Error와 Exception을 명확히 구분하는 것은 Java 예외 처리의 첫걸음이에요.
앞으로 각각을 어떤 방식으로 처리해야 할지 방향성을 잡는 데도 큰 도움이 됩니다.
🧩 Java에서 Exception의 역할
예외(Exception)는 단순히 프로그램을 멈추게 만드는 장애 요소가 아닙니다.
오히려 안정적이고 견고한 소프트웨어 개발을 위한 핵심 도구로써 중요한 역할을 합니다.
Java에서는 예외 처리를 통해 예측 가능한 오류에 유연하게 대응할 수 있도록 구조화되어 있어요.
🛡️ 프로그램의 예외적 흐름을 제어한다
예외는 프로그램 실행 중 특정 상황에서 정상적인 흐름을 잠시 멈추고, 예외 처리 블록으로 흐름을 이동시켜줍니다.
이 과정을 통해 프로그램이 비정상 종료되는 것을 막고, 사용자의 불편을 최소화할 수 있어요.
💎 핵심 포인트:
예외가 발생하면 곧바로 catch 블록으로 흐름이 이동하며, 이후 필요한 조치를 취한 뒤 프로그램을 계속 실행시킬 수 있습니다.
📦 코드 가독성과 유지 보수성 향상
명확한 예외 처리는 개발자가 코드의 흐름을 더 쉽게 이해하고, 문제 발생 위치를 빠르게 파악할 수 있게 해줍니다.
특히, 다양한 예외 클래스와 사용자 정의 예외(Custom Exception)를 활용하면, 비즈니스 로직별로 예외 상황을 세분화할 수 있어요.
- 🧭try-catch-finally 구조를 통해 예외 발생에도 안정적인 흐름 유지
- 🔍예외 메시지를 통해 문제의 원인과 위치 파악
- 📛사용자 정의 예외로 업무 흐름에 맞는 예외 분기 처리 가능
즉, 예외 처리는 단순히 문제를 막는 것이 아니라, 문제가 발생하더라도 중단되지 않고 회복할 수 있도록 설계하는 방법입니다.
프로그램의 안정성과 완성도를 높이기 위해 반드시 익혀야 할 개념이에요.
🛠️ 예외 처리 기본 구조 (try-catch-finally)
Java에서 예외 처리의 기본은 try-catch-finally 구문을 활용하는 것입니다.
이 구조는 예외가 발생할 가능성이 있는 코드 블록을 감싸고, 문제가 생겼을 때 어떻게 처리할지를 명확히 정의해줍니다.
🧪 try 블록
예외가 발생할 수 있는 코드는 try 블록 안에 작성합니다.
예외가 발생하지 않으면 정상적으로 실행되고, 예외가 발생하면 곧바로 catch로 넘어갑니다.
🧲 catch 블록
발생한 예외에 맞는 처리 코드를 작성하는 영역입니다.
여기서 예외 로그를 남기거나 사용자에게 알림을 줄 수 있어요.
catch는 여러 개를 나열하여 다양한 예외 상황에 개별 대응할 수 있습니다.
🔁 finally 블록
예외 발생 여부와 관계없이 반드시 실행되는 영역입니다.
주로 파일 닫기, DB 연결 해제와 같은 정리 작업에 활용됩니다.
옵션이지만 자주 사용됩니다.
try {
// 예외 발생 가능성 있는 코드
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("0으로 나눌 수 없습니다.");
} finally {
System.out.println("항상 실행되는 블록입니다.");
}
- ✅try는 반드시 catch 또는 finally와 함께 사용해야 합니다
- 📎catch는 다양한 예외를 구분하여 사용할 수 있습니다
- 🔚finally는 자원 해제 등 마무리 작업에 유용합니다
이 구조를 잘 이해하고 활용하면, 복잡한 상황에서도 예외를 안전하게 처리할 수 있습니다.
기본에 충실한 try-catch-finally는 Java 예외 처리의 뼈대라고 할 수 있어요.
📚 Checked와 Unchecked 예외의 이해
Java에서 예외는 크게 두 가지로 나뉩니다.
바로 Checked Exception과 Unchecked Exception이에요.
이 두 개념은 예외 처리의 시점과 의무 여부에 따라 구분되며, 개발자라면 반드시 이해하고 있어야 합니다.
📝 Checked Exception (확인된 예외)
컴파일 시점에 반드시 처리해야 하는 예외로, 예외 처리하지 않으면 컴파일 에러가 발생합니다.
파일 입출력, 네트워크 통신, 데이터베이스 작업처럼 외부 자원과 연동되는 경우 주로 발생해요.
💡 TIP: 대표적인 Checked 예외로는 IOException, SQLException, ClassNotFoundException 등이 있어요.
⚠️ Unchecked Exception (확인되지 않은 예외)
런타임(Runtime) 중 발생하며, 컴파일 시점에 처리하지 않아도 되는 예외입니다.
코드의 논리적 오류나 프로그래밍 실수로 인해 주로 발생하죠.
NullPointerException, ArrayIndexOutOfBoundsException 등이 대표적입니다.
💎 핵심 포인트:
Checked 예외는 반드시 처리해야 하지만, Unchecked 예외는 선택적으로 처리할 수 있어요. 하지만 처리하지 않으면 예기치 않은 오류로 이어질 수 있습니다.
| 구분 | Checked Exception | Unchecked Exception |
|---|---|---|
| 처리 시점 | 컴파일 타임 | 런타임 |
| 예외 처리 필수 여부 | 필수 | 선택 |
| 대표 예외 | IOException, SQLException | NullPointerException, ArithmeticException |
이러한 구분을 통해 개발자는 상황에 맞게 예외를 설계하고 처리할 수 있습니다.
프로젝트의 성격에 따라 Checked 예외 중심으로 설계할 수도 있고, Unchecked 예외에 집중할 수도 있어요.
중요한 건, 예외 발생 가능성을 인지하고 적절한 대응을 미리 준비하는 것입니다.
🔍 컬렉션 사용 시 발생하는 대표 예외
Java의 컬렉션 프레임워크(List, Set, Map 등)는 데이터를 효율적으로 다루기 위한 강력한 도구입니다.
하지만 잘못된 접근이나 조작으로 인해 다양한 예외가 발생할 수 있어요.
컬렉션을 안전하게 사용하려면 어떤 예외가 발생할 수 있는지를 이해하고, 이를 사전에 방지하거나 적절히 처리하는 습관이 중요합니다.
📭 IndexOutOfBoundsException
List의 인덱스 범위를 벗어난 값을 조회하거나 수정할 때 발생합니다.
예를 들어 존재하지 않는 인덱스를 참조하면 이 예외가 발생해요.
List<String> list = new ArrayList<>();
list.add("apple");
System.out.println(list.get(5)); // 존재하지 않는 인덱스
🧨 NullPointerException
컬렉션에 null이 들어있거나, 컬렉션 자체가 null인데 메서드를 호출하려 할 때 발생합니다.
가장 자주 발생하는 예외 중 하나예요.
⛔ ConcurrentModificationException
컬렉션을 반복(iteration)하는 도중에 해당 컬렉션을 수정할 경우 발생합니다.
Iterator를 사용할 때 주의해야 하며, remove()는 Iterator의 메서드를 사용해야 안전합니다.
💎 핵심 포인트:
컬렉션은 유용하지만, 잘못된 사용은 예외를 발생시킵니다. 반복문 내 수정, 잘못된 인덱스 접근, null 상태 접근은 대표적인 원인이에요.
- 📌List 조회 전 인덱스 범위 반드시 확인
- 🧪null 체크는 모든 컬렉션 조작 전 필수
- 🛠️반복 중 컬렉션 수정 시 Iterator 사용
자바 컬렉션은 굉장히 유용하지만, 예외에 대한 이해 없이 사용하면 디버깅에 많은 시간과 노력이 들 수 있습니다.
위와 같은 대표적인 예외들은 실무에서 자주 마주치는 만큼, 미리 알아두면 훨씬 수월하게 대처할 수 있어요.
❓ 자바 예외 처리 자주 묻는 질문 (FAQ)
Exception과 Error는 꼭 구분해서 알아야 하나요?
예외 처리를 꼭 해야 하나요?
Unchecked 예외도 catch로 잡아야 하나요?
try 없이 catch만 사용할 수 있나요?
finally는 꼭 작성해야 하나요?
사용자 정의 예외는 언제 필요한가요?
컬렉션 사용 시 예외를 줄이는 방법은?
예외 발생 시 로그를 꼭 남겨야 하나요?
🧷 Java 예외 처리 개념, 구조, 유형까지 한눈에 정리!
이번 글에서는 Java 개발에서 절대 빠질 수 없는 예외 처리의 개념과 구조, 그리고 Exception과 Error의 차이에 대해 상세히 다뤘습니다.
try-catch-finally의 기본 구문부터 Checked/Unchecked 예외의 구분, 실무에서 자주 마주치는 컬렉션 관련 예외까지 실제 코드와 함께 설명드렸어요.
또한, 자주 묻는 질문을 FAQ로 정리하여 예외 처리에 대한 궁금증도 함께 해결할 수 있도록 했습니다.
예외를 단순히 문제로만 보지 않고, 더 안정적이고 완성도 높은 코드를 위한 필수 도구로 받아들이는 시각이 중요합니다.
지금까지 설명드린 내용을 바탕으로 여러분의 코드 품질을 한층 더 향상시켜보세요!
🏷️ 관련 태그 : Java예외처리, Exception과Error, trycatchfinally, CheckedException, UncheckedException, 자바기초, 자바컬렉션, 예외구조, 예외차이점, 자바개발팁