☕️ 김영한의 실전 자바 - 중급 1편 을 듣고 작성하는 복습 블로그 입니다.
0. 배경
프로그램이 항상 정상 동작되지만은 않는다
거의 대부분의 프로그램은 오류가 발생하는데 이런 오류를 어떻게 처리하느냐에 따라 개발자의 실력이 결정된다
오늘은 이런 오류를 처리하는 예외처리에 대해서 알아보자
1. 예외 계층
자바는 프로그램 실행 중에 발생할 수 있는 예상치 못한 상황을 처리하기 위한 메커니즘을 제공한다.
이것이 바로 예외인데 프로그램의 안전성과 신뢰성을 높이는데 아주 중요한 역할을 한다.

자바의 예외 계층은 위와 같다
- Object : 예외도 객체이기 때문에 최상위 부모엔 Object 가 있다
- Throwable : 최상위 예외
- Erorr : 애플리케이션에서 복구가 불가능한 시스템 예외다. 해결할 수 없기 때문에 개발자가 예외를 잡으려고 해서는 안된다
- Exception : 체크 예외
- 애플리케이션 로직에서 사용할 수 있는 최상위 예외
- Exception 과 하위 예외는 컴파일러가 체크하는 체크 예외다
- RuntimeException : 언체크 예외, 런타임 예외
- 컴파일러가 체크하지 않는 언체크 예외
- RuntimeException 과 자식 예외는 모두 언체크 예외다
2. 예외 기본 규칙
예외는 마치 폭탄 돌리기와 같다 💣
예외가 발생하면 잡아서 처리하거나 처리할 수 없으면 밖으로 던져야 한다
Main → Service → Client 가 있는 상황에서 Client 에서 🔥 예외가 발생했다 !!!
예외 처리
🔥 Client → 🧯 Service → 🕊️ Main
- 🔥 Client 에서 예외가 발생하면, Service 로 예외를 던진다
- 🧯 Service 에서 예외를 처리했다
- 🕊️ 그러면 Main 에서는 정상 흐름으로 사용할 수 있다
예외 던짐
🔥 Client → 🔥 Service → 🔥 Main
- 🔥 Client 에서 예외가 발생하면, Service 로 예외를 던진다
- 🔥 Service 도 처리할 수 없어서 Main 으로 예외를 던진다
- 🔥 Main 도 밖으로 예외를 던지고 결국 예외 로그를 출력하면서 시스템이 종료된다
예외에 대한 2가지 기본 규칙
- 예외는 잡아서 처리하거나 밖으로 던져야 한다
- 예외를 잡거나 던질 때 지정한 예외 뿐만 아니라 그 예외의 자식들도 함께 처리할 수 있다
3. 예외 사용하기
예외 던지기
public class Client {
public void call() throws MyCheckedException {
throw new MyCheckedException("ex");
}
}
- throw 는 새로운 예외를 발생시킨다
- throws 는 발생시킨 예외를 메서드 밖으로 던진다
예외 잡기
try {
// 정상 코드
} catch (예외클래스 e) {
// 예외 발생시 처리 코드
} finally {
// try 실행 후 무조건 실행되어야 하는 코드
}
- 던져진 예외는 try~catch~finally 문으로 잡을 수 있다
- try 내에는 정상 코드가 들어가 들어간다
- 만약, try 에 있는 코드 중 예외가 발생했고, catch 에 해당 예외가 선언되어 있으면 catch 로 들어간다
- try 가 실행되고 난 후 finally 에 있는 코드가 실행된다
4. 체크 / 언체크 예외
4-1. 체크 예외
체크 예외는 위의 예외 계층에서 Exception 을 상속받는 예외다
잡아서 처리하거나 밖으로 던지도록 선언해야 한다
그렇지 않으면 🚨 컴파일 오류가 발생한다
체크 예외 만들기
public class MyCheckedException extends Exception {
public MyCheckedException(String message) {
super(message);
}
}
- 체크 예외를 만들려면 Exception 을 상속받으면 된다
- super(message) 로 전달된 메시지는 Thrwable 의 detailMessage 에 보관된다
체크 예외의 장단점
👍 장점
- 개발자가 실수로 예외를 누락하지 않도록 컴파일러를 통해 문제를 잡아준다
- 개발자는 어떤 체크 예외가 발생하는지 쉽게 파악할 수 있다
👎 단점
- 개발자가 모든 체크 예외를 반드시 잡거나 던지도록 처리해야 하므로 번거롭다
- 크게 신경쓰고 싶지 않는 예외까지 모두 챙겨야 한다
4-2. 언체크 예외
언체크 예외는 위의 예외 계층에서 RuntimeException 을 상속받는 예외다
컴파일러가 예외를 체크하지 않기 때문에 잡아서 처리하지 않아도 된다
언체크 예외 클래스 생성
public class MyUncheckedException extends RuntimeException {
public MyUncheckedException(String message) {
super(message);
}
}
- RuntimeException 을 상속받으면 언체크 예외 클래스를 만들 수 있다
언체크 예외의 장단점
👍 장점
- 신경쓰고 싶지 않은 언체크 예외를 무시할 수 있다
- 체크 예외의 경우 처리할 수 없는 예외를 밖으로 던지려면 항상 throws 예외를 선언해야 하지만, 언체크 예외는 생략할 수 있다
👎 단점
- 개발자가 실수로 예외를 누락할 수 있다
- 체크 예외는 컴파일러를 통해 예외 누락을 잡아준다
5. 실무 예외 처리 방안
실무에서는 해결할 수 없는 오류들이 많이 발생한다.
하지만, 상대 네트워크 서버에 문제가 발생해서 통신이 불가능한 경우 내가 재시도한다고 해도 해결할 수 없다
그리고 프로그램이 복잡해지면서 연결되어 있는 클래스가 많다
이럴 때 체크 예외와 언체크 예외를 사용하는 예를 생각해보자
✅ 체크 예외 사용 시나리오
- 수 많은 클래스가 자신만의 예외를 모두 체크 예외로 만들어서 전달한다
- Service 를 호출하는 곳에선 던지는 체크 예외들을 모두 처리해야 한다
- 만약 처리할 수 없으면 밖으로 던진다
class Service {
void sendMessage(String data) throws NetworkException, DatabaseException, ...{
...
}
}
- 모든 체크 예외를 하나씩 밖으로 던져야 한다
- 라이브러리가 늘어날 수록 throws 에 적는 예외는 늘어난다
☑️ 언체크 예외 사용 시나리오
- 수 많은 클래스가 자신만의 예외를 모두 언체크 예외로 만들어서 전달한다
- Service 를 호출하는 곳에선 던지는 언체크 예외를 모두 처리하지 않아도 된다
class Service {
void sendMessage(String data) {
...
}
}
- 언체크 예외이므로 throws 를 선언하지 않아도 된다
- 사용하는 라이브러리가 늘어나서 언체크 예외가 늘어나는 경우 본인이 필요한 예외만 잡으면 된다
→ 그렇기 때문에 실무에서는 ☑️ 언체크 예외를 많이 사용한다
→ 그리고 처리할 수 없는 예외의 경우에는 공통으로 처리한다
6. try-with-resource
- try 가 끝나면 외부 자원을 반납하는 패턴을 많이 사용한다
- 그렇기 때문에 자바 7부터 try with resource 라는 기능이 추가되었다
public class TestClass implements AutoCloseable {
...
@Override
public void close(){
System.out.println("TestClass.close");
disconnect();
}
}
try-with-resource 를 사용하려면
- 정상 코드에 사용할 클래스에서 AutoCloseable 을 구현
- close() 메소드 오버라이딩
- close() 메소드에서 예외처리가 끝나고 실행할 코드 작성
한 후
try (TestClass test = new TestClass()) {
// 리소스를 사용하는 코드
}
- try ~ catch 문의 try 에서 객체를 생성해 넣어준다
- 그러면 try 블럭이 끝났을 때 자동으로 TestClass 내부의 close() 를 호출한다
- 예외가 발생하면 try 에서 벗어나는 순간 close() 가 호출된다.
- 즉, try 가 호출되고 catch 가 호출된다
try-with-resource 의 장점
- 리소스 누수 방지 : 모든 리소스가 제대로 닫히도록 보장한다
- 코드 간결성 및 가독성 향상 : 명시적인 close() 호출이 필요없다
- 스코프 범위 한정 : 리소스로 사용되는 client 변수의 스코프가 try 블럭 안으로 한정된다
- 조금 더 빠른 자원 해제 : try 블럭이 끝나면 즉시 close() 를 호출한다
'🌱 인프런 > ☕️ 김영한의 실전 자바 - 중급 1편' 카테고리의 다른 글
| 자바 Object 클래스 (1) | 2025.09.01 |
|---|---|
| 자바 래퍼, Class 총정리 (0) | 2025.07.19 |
| 자바 열거형 ENUM 총정리 (2) | 2025.07.10 |
| 자바 중첩 클래스와 내부 클래스 (3) | 2025.07.09 |
| 자바 날짜와 시간 라이브러리 총정리 (0) | 2025.07.07 |