데이터 엔지니어링

패스트캠퍼스 환급챌린지 28일차: 데이터엔지니어링 초격차 강의 후기

Big Byte 2025. 4. 28. 23:43

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

 

예상치 못한 상황 대처법! 자바 예외 처리로 프로그램 안정성 UP! 🛡️🚦💣

 

안녕하세요 여러분! 다시 만나 정말 반가워요! 🤩

 

와~ 지난 시간에는 추상 클래스와 인터페이스를 배우면서 코드의 유연성과 확장성을 높이는 방법을 알아봤죠! 🏗️🤝 마치 건물의 뼈대를 세우고(추상 클래스), 다양한 부품들이 지켜야 할 규격(인터페이스)을 정하는 것과 같았어요. 덕분에 우리는 더욱 체계적이고 재사용 가능한 코드를 설계할 수 있게 되었습니다! 👍

 

하지만 우리가 아무리 설계를 잘하고 코드를 완벽하게 작성하려고 노력해도, 프로그램이 실행되는 동안 예상치 못한 문제들은 언제든 발생할 수 있어요! 😱

 

예를 들어, 사용자가 숫자를 입력해야 하는 곳에 문자를 입력하거나, 인터넷 연결이 갑자기 끊어지거나, 존재하지 않는 파일을 열려고 시도하는 경우 등이 있겠죠? 이런 얘기치 못한 상황들을 우리는 예외(Exception) 또는 오류(Error)라고 부릅니다.

 

만약 이런 예외 상황에 제대로 대처하지 않으면, 우리 프로그램은 속수무책으로 멈춰버리거나(crash!), 사용자를 당황하게 만드는 빨간 에러 메시지만 잔뜩 보여주게 될 거예요. 💣 마치 잘 달리던 자동차가 갑자기 고장 나서 멈춰버리는 것과 같죠!

 

그래서 오늘은! 이렇게 예측 불가능한 상황에서도 우리 프로그램이 최대한 안정적으로 계속 작동하거나, 혹은 문제가 생겼을 때 사용자에게 친절하게 안내하고 안전하게 종료될 수 있도록 도와주는 예외 처리(Exception Handling) 메커니즘에 대해 배워볼 거예요! 준비되셨나요? 

1. 예외 처리는 왜 필요할까? (목적) 🤔🛡️

"에이, 그냥 에러 나면 끄고 다시 켜면 되는 거 아니에요?" 라고 생각할 수도 있지만, 그건 너무 무책임하겠죠? 😉 예외 처리는 단순히 프로그램이 멈추는 것을 막는 것 이상의 중요한 목적들을 가지고 있어요.

 

  • 프로그램 비정상 종료 방지: 가장 기본적인 목적! 예외가 발생했을 때 프로그램이 갑자기 죽어버리는 것을 막고, 계속 실행해야 할 로직이 있다면 이어서 실행할 수 있게 해줘요. 🚦
  • 정상적인 흐름 유지: 문제가 발생하더라도, 예외를 '잡아서(catch)' 적절히 처리한 후, 프로그램이 원래 하려고 했던 작업 흐름으로 최대한 복귀하거나 대체 경로를 제공할 수 있어요. (예: "파일을 열 수 없습니다. 다른 파일을 선택해주세요.") 🔄
  • 문제 상황 알림 및 로깅: 사용자에게 어떤 문제가 발생했는지 친절하게 알려주거나(예: "네트워크 연결을 확인해주세요."), 개발자가 나중에 문제를 분석할 수 있도록 로그(기록)를 남길 수 있어요. ✍️📊
  • 자원 해제 보장: 파일, 네트워크 연결, 데이터베이스 연결 등 사용 후 반드시 닫아주거나 해제해야 하는 자원들이 있어요. 예외 발생 여부와 상관없이 이런 자원들을 안전하게 해제하는 것을 보장해줘요. (이건 finally에서 다시!) 🧹✨

결국 예외 처리는 우리 프로그램을 더욱 견고(Robust)하고 신뢰성(Reliable) 있게 만들어주는 필수적인 안전 장치라고 할 수 있습니다! 마치 건물의 비상구나 소화 장치 같은 거죠! 🔥👨‍🚒

 

2. try-catch: 예외를 잡아서 처리하자! 🎣🚨

자, 그럼 실제로 예외를 어떻게 다룰 수 있을까요? 자바에서는 trycatch라는 키워드를 사용해서 예외 처리 구조를 만듭니다.

  • try { ... }: 이 블록 안에는 예외가 발생할 가능성이 있는 코드를 넣습니다. 마치 "일단 시도해봐!"라고 말하는 것과 같아요. 여기는 잠재적인 위험 구역이죠! ⚠️
  • catch (처리할_예외_타입 변수명) { ... }: try 블록 안에서 특정 타입의 예외가 발생했을 경우, 그 예외를 잡아서(catch) 처리하는 코드를 이 블록 안에 작성합니다. 예외 상황에 대한 비상 대책반 같은 역할이죠! 👮‍♀️

마치 그물을 던져놓고(try), 물고기가 걸리면(예외 발생), 그물을 걷어 올려 처리하는(catch) 모습과 비슷해요! 😉

public class ExceptionTest {

    public static void main(String[] args) {
        System.out.println("프로그램 시작!");

        try {
            // 예외가 발생할 가능성이 있는 코드
            int[] numbers = {1, 2, 3};
            System.out.println("배열의 5번째 요소 접근 시도...");
            System.out.println(numbers[4]); // 🚨 존재하지 않는 인덱스 접근! 여기서 예외 발생!

            // 이 아래 코드는 예외 발생 시 실행되지 않음
            System.out.println("이 메시지는 출력되지 않아요!");

        } catch (ArrayIndexOutOfBoundsException e) {
            // ArrayIndexOutOfBoundsException 예외가 발생했을 때 실행될 코드
            System.out.println("🚨 이런! 배열의 범위를 벗어났어요!");
            System.out.println("예외 메시지: " + e.getMessage()); // 예외 객체에 담긴 정보 활용
            // e.printStackTrace(); // 개발 시 예외 발생 경로를 추적할 때 유용! (주석 처리)

        } catch (Exception e) {
             // 혹시 다른 종류의 예외가 발생할 경우를 대비 (포괄적 처리)
             System.out.println("🚨 예상치 못한 다른 예외 발생!");
             System.out.println("예외 메시지: " + e.getMessage());
        }

        System.out.println("프로그램 정상 종료!"); // catch 블록 실행 후 여기로 와서 계속 실행됨!
    }
}

위 예제에서 numbers[4]는 배열의 크기(3)를 벗어난 접근이라 ArrayIndexOutOfBoundsException이라는 예외를 발생시킵니다. try 블록에서 예외가 발생하는 순간, 실행은 즉시 멈추고 해당 예외를 처리할 수 있는 catch 블록으로 점프합니다.

 

여기서는 첫 번째 catch 블록이 이 예외를 잡아서 "배열 범위를 벗어났다"는 메시지를 출력하고, 프로그램은 비정상 종료되지 않고 마지막 "프로그램 정상 종료!" 메시지까지 출력하게 됩니다. 만약 catch 블록이 없었다면, 프로그램은 에러 메시지를 뿜어내며 그 자리에서 멈춰버렸을 거예요! 😱

 

하나의 try 블록 뒤에는 여러 개의 catch 블록을 두어서 다양한 종류의 예외를 각각 다르게 처리할 수도 있습니다. (위 예제의 두 번째 catch 블록처럼요!)

 

3. finally: 예외 발생 여부와 상관없이 항상 실행! ✨🧹

때로는 예외가 발생하든 안 하든, 심지어 catch 블록에서 예외를 처리했든 못했든, 반드시 실행되어야 하는 코드가 있습니다. 예를 들어, 파일을 열어서 작업했다면 작업이 성공하든 실패하든 파일을 닫아줘야 하고, 네트워크 연결을 사용했다면 연결을 끊어줘야 하죠. 이런 '마무리 작업' 또는 '뒷정리'를 위한 코드를 넣는 곳이 바로 finally 블록입니다!

  • finally { ... }: 이 블록 안의 코드는 try 블록의 실행이 끝나면 무조건 실행됩니다. 예외가 발생해서 catch로 가더라도 catch 블록 실행 후에 finally가 실행되고, 예외가 발생하지 않아도 try 블록 실행 후에 finally가 실행됩니다.

마치 식당에서 식사가 끝나면(try 성공), 혹은 음식을 쏟아서 치워야 할 때(catch), 어쨌든 마지막에는 테이블을 정리하는(finally) 것과 같아요!

import java.util.Scanner;

public class FinallyTest {

    public static void main(String[] args) {
        Scanner scanner = null; // Scanner 자원 선언

        try {
            scanner = new Scanner(System.in); // 자원 할당 (파일 열기, 네트워크 연결 등과 유사)
            System.out.print("나눌 숫자를 입력하세요: ");
            int num1 = scanner.nextInt();

            System.out.print("나누는 숫자를 입력하세요 (0 제외): ");
            int num2 = scanner.nextInt();

            System.out.println("나눗셈 결과: " + (num1 / num2)); // 0으로 나누면 ArithmeticException 발생!

        } catch (ArithmeticException e) {
            System.out.println("🚨 0으로 나눌 수 없어요!");
        } catch (Exception e) { // 다른 예외 처리 (예: 숫자가 아닌 문자 입력 시 InputMismatchException)
            System.out.println("🚨 잘못된 입력입니다! 숫자를 입력해주세요.");
        } finally {
            // 예외 발생 여부와 상관없이 무조건 실행!
            System.out.println("--- finally 블록 실행됨 ---");
            if (scanner != null) {
                System.out.println("Scanner 자원을 닫습니다.");
                scanner.close(); // ✨ 자원 해제! 중요!
            }
        }

        System.out.println("프로그램 종료.");
    }
}

위 예제에서는 사용자의 입력을 받기 위해 Scanner 객체를 사용합니다. 사용자가 0으로 나누려고 하거나 숫자가 아닌 값을 입력하면 예외가 발생하겠죠?

 

어떤 상황이든, finally 블록은 항상 실행되어 scanner.close()를 호출함으로써 사용했던 자원을 안전하게 닫아줍니다. 이렇게 finally를 사용하면 자원 누수(Resource Leak)를 방지하고 프로그램을 더 안정적으로 만들 수 있습니다. 💪

 

4. 정리하며 📝

휴~ 오늘은 프로그램의 안정성을 책임지는 든든한 방패, 예외 처리에 대해 알아봤습니다! 🛡️🚦 예상치 못한 문제 상황(예외)을 감지하고(try), 적절히 대응하며(catch), 어떤 상황에서도 마무리 작업을 보장하는(finally) 방법을 배웠어요.

 

처음에는 try-catch 구조가 조금 어색할 수 있지만, 이 강력한 도구를 잘 활용하면 사용자를 당황시키지 않고, 중요한 데이터나 자원을 안전하게 보호하는 견고한 프로그램을 만들 수 있답니다! 👍

오늘의 핵심 내용을 다시 한번 돌이켜볼까요?

 

  • 예외 처리의 목적: 프로그램 비정상 종료 방지, 정상 흐름 유지, 문제 알림/로깅, 자원 해제 보장! 🛡️
  • try 블록: 예외 발생 가능성이 있는 코드를 감싸는 영역. "일단 시도해!" ⚠️
  • catch 블록: try에서 특정 예외 발생 시 실행되는 비상 대책반. "내가 처리할게!" 🎣🚨
  • finally 블록: 예외 발생 여부와 상관없이 항상 실행되는 마무리 영역. "뒷정리는 필수!" ✨🧹

이제 코드를 작성할 때 "여기서 혹시 예외가 발생할 수 있지 않을까?" 하고 한번 더 생각해보는 습관을 들여보세요! 여러분의 코드가 훨씬 더 튼튼해질 거예요! 💪💻

 

 

이야~ 정신없이 예외 처리를 하다 보니 벌써 월요일 밤이네요! 🌃 새로운 한 주를 시작하며 예외 처리라는 중요한 개념까지 정복하시느라 정말 정말 수고 많으셨습니다! 👏 오늘 배운 내용들이 앞으로 여러분의 코딩 여정에 든든한 발판이 되기를 바랍니다! 😊

 

피곤한 월요일, 모두 정말 고생하셨어요! 굿밤 보내시고, 우리는 내일 또 만나요! 👋

 

https://abit.ly/lisbva