λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
⌨️ Language/Java

[Java] μ˜ˆμ™Έ 처리 μ™„μ „ 정볡 β‘  : κ°œλ…λΆ€ν„° try-catchκΉŒμ§€

by hyebin (Helia) 2025. 5. 16.
λ°˜μ‘ν˜•

λͺ©μ°¨

     

     

    ν”„λ‘œκ·Έλž¨μ„ κ°œλ°œν•˜λ‹€ 보면 μ˜ˆμƒμΉ˜ λͺ»ν•œ 상황이 λ°œμƒν•˜κΈ° λ§ˆλ ¨μž…λ‹ˆλ‹€. μ‚¬μš©μžκ°€ 잘λͺ»λœ μž…λ ₯을 ν•˜κ±°λ‚˜, λ„€νŠΈμ›Œν¬ 연결이 λŠκΈ°κ±°λ‚˜, 파일이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” λ“± λ‹€μ–‘ν•œ λ¬Έμ œκ°€ 생길 수 있죠.

     

    μžλ°”μ—μ„œλŠ” 이런 μ˜ˆμ™Έ 상황을 효과적으둜 닀루기 μœ„ν•œ μ˜ˆμ™Έ 처리(Exception Handling) λ©”μ»€λ‹ˆμ¦˜μ„ μ œκ³΅ν•©λ‹ˆλ‹€.

    μ˜ˆμ™Έ 처리λ₯Ό μž˜ν•˜λ©΄ ν”„λ‘œκ·Έλž¨μ΄ μ€‘λ‹¨λ˜μ§€ μ•Šκ³ , μ‚¬μš©μžμ—κ²Œ μΉœμ ˆν•œ λ©”μ‹œμ§€λ₯Ό 보여주며, 문제의 원인을 μΆ”μ ν•˜κΈ° μ‰¬μš΄ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆμ–΄μš”.

     

    μ˜€λŠ˜μ€ μžλ°” μ˜ˆμ™Έ 처리의 κΈ°λ³Έ κ°œλ…κ³Ό κ΅¬ν˜„ 방법에 λŒ€ν•΄ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.


    πŸ’₯ μ˜ˆμ™Έλž€ 무엇인가?

    μ˜ˆμ™Έ(Exception)λŠ” ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ 쀑에 λ°œμƒν•˜λŠ” 예기치 μ•Šμ€ 이벀트둜, ν”„λ‘œκ·Έλž¨μ˜ 정상적인 흐름을 λ°©ν•΄ν•©λ‹ˆλ‹€.

     

    μ—λŸ¬(Error) vs μ˜ˆμ™Έ(Exception)

    μ—λŸ¬(Error)λŠ” μ‹œμŠ€ν…œ 레벨의 μ‹¬κ°ν•œ 문제둜, λŒ€λΆ€λΆ„ ν”„λ‘œκ·Έλž¨μ—μ„œ μ²˜λ¦¬ν•  수 μ—†μŠ΅λ‹ˆλ‹€. OutOfMemoryErrorλ‚˜ StackOverflowError 같은 μ—λŸ¬λŠ” JVM 자체의 λ¬Έμ œλ‚˜ λ¦¬μ†ŒμŠ€ λΆ€μ‘± λ“±μœΌλ‘œ λ°œμƒν•˜λ©°, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ½”λ“œμ—μ„œ λ³΅κ΅¬ν•˜κΈ° μ–΄λ ΅μŠ΅λ‹ˆλ‹€.

     

    μ˜ˆμ™Έ(Exception)λŠ” ν”„λ‘œκ·Έλž¨ μ½”λ“œμ—μ„œ μ²˜λ¦¬ν•  수 μžˆλŠ” λ¬Έμ œμž…λ‹ˆλ‹€. μ μ ˆν•œ 처리λ₯Ό 톡해 ν”„λ‘œκ·Έλž¨μ„ 계속 μ‹€ν–‰ν•  κ°€λŠ₯성이 있죠. NullPointerExceptionμ΄λ‚˜ FileNotFoundException 같은 μ˜ˆμ™ΈλŠ” μ μ ˆν•œ μ˜ˆμ™Έ 처리 λ©”μ»€λ‹ˆμ¦˜μ„ 톡해 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

     

    μ™œ μ˜ˆμ™Έ μ²˜λ¦¬κ°€ ν•„μš”ν• κΉŒ?

    1. ν”„λ‘œκ·Έλž¨ μ•ˆμ •μ„± ν–₯상: μ˜ˆμ™Έ λ°œμƒ μ‹œμ—λ„ ν”„λ‘œκ·Έλž¨μ΄ 비정상 μ’…λ£Œλ˜μ§€ μ•Šκ³  계속 싀행될 수 있게 함
    2. 디버깅 μš©μ΄μ„±: μ˜ˆμ™Έ λ°œμƒ μ‹œ 원인을 더 μ‰½κ²Œ νŒŒμ•…ν•  수 있음
    3. μ½”λ“œ ν’ˆμ§ˆ ν–₯상: μ˜ˆμ™Έ 상황을 미리 κ³ λ €ν•˜μ—¬ 더 κ²¬κ³ ν•œ μ½”λ“œ μž‘μ„± κ°€λŠ₯
    4. μœ μ§€λ³΄μˆ˜μ„± 증가: μ˜ˆμ™Έ 처리 λ‘œμ§μ„ λΆ„λ¦¬ν•¨μœΌλ‘œμ¨ μ½”λ“œ 가독성과 μœ μ§€λ³΄μˆ˜μ„± ν–₯상

     

    μ˜ˆμ™Έ 처리의 원칙

    효과적으둜 μ˜ˆμ™Έ 처리λ₯Ό μœ„ν•΄ λͺ‡ κ°€μ§€ κΈ°λ³Έ 원칙이 μžˆμŠ΅λ‹ˆλ‹€.

    1. μ μ ˆν•œ λ²”μœ„μ—μ„œ 처리: μ˜ˆμ™Έλ₯Ό κ°€μž₯ μ μ ˆν•˜κ²Œ μ²˜λ¦¬ν•  수 μžˆλŠ” μœ„μΉ˜μ—μ„œ 처리
    2. ꡬ체적인 μ˜ˆμ™Έ 포착: κ°€λŠ₯ν•œ ν•œ ꡬ체적인 μ˜ˆμ™Έ νƒ€μž…μ„ μ‚¬μš©ν•˜μ—¬ 포착
    3. 의미 μžˆλŠ” 정보 제곡: μ˜ˆμ™Έ λ©”μ‹œμ§€μ— 문제 해결에 도움이 λ˜λŠ” 정보 포함
    4. λ¦¬μ†ŒμŠ€ 정리: μ˜ˆμ™Έ λ°œμƒ 여뢀와 관계없이 λ¦¬μ†ŒμŠ€(파일, λ„€νŠΈμ›Œν¬ μ—°κ²° λ“±)λ₯Ό 적절히 정리

    πŸ“š μ˜ˆμ™Έμ˜ μ’…λ₯˜ (Checked vs Unchecked)

    Checked Exception

    컴파일 νƒ€μž„μ— ν™•μΈλ˜λŠ” μ˜ˆμ™Έλ‘œ, λ°˜λ“œμ‹œ λͺ…μ‹œμ μΈ μ˜ˆμ™Έ μ²˜λ¦¬κ°€ ν•„μš”ν•©λ‹ˆλ‹€.

    μ΄λŸ¬ν•œ μ˜ˆμ™ΈλŠ” try-catch λΈ”λ‘μœΌλ‘œ μ²˜λ¦¬ν•˜κ±°λ‚˜ throws ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ λ©”μ„œλ“œ 선언뢀에 λͺ…μ‹œν•΄μ•Ό ν•©λ‹ˆλ‹€.

     

    Checked Exception은 주둜 ν”„λ‘œκ·Έλž¨ μ™ΈλΆ€ μš”μΈμ— μ˜ν•΄ λ°œμƒν•˜λŠ” μ˜ˆμ™Έλ‘œ, κ°œλ°œμžκ°€ 적절히 λŒ€μ‘ν•  κ²ƒμœΌλ‘œ κΈ°λŒ€λ˜λŠ” μƒν™©μ—μ„œ μ‚¬μš©λ©λ‹ˆλ‹€. IOException, SQLException, ClassNotFoundException 등이 λŒ€ν‘œμ μΈ Checked Exceptionμž…λ‹ˆλ‹€.

    import java.io.FileReader;
    import java.io.IOException;
    
    public class CheckedExceptionExample {
        public static void main(String[] args) {
            try {
                FileReader file = new FileReader("non-existent-file.txt");
            } catch (IOException e) {
                System.out.println("νŒŒμΌμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€: " + e.getMessage());
            }
        }
    }

     

     

    Unchecked Exception

    RuntimeException ν΄λž˜μŠ€μ™€ κ·Έ ν•˜μœ„ 클래슀둜, μ»΄νŒŒμΌλŸ¬κ°€ μ˜ˆμ™Έ 처리λ₯Ό κ°•μ œν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

    μ΄λŸ¬ν•œ μ˜ˆμ™ΈλŠ” 주둜 ν”„λ‘œκ·Έλž˜λ° 였λ₯˜μ— μ˜ν•΄ λ°œμƒν•˜λ©°, μ½”λ“œλ₯Ό μˆ˜μ •ν•˜μ—¬ μ˜ˆλ°©ν•˜λŠ” 것이 λ°”λžŒμ§ν•©λ‹ˆλ‹€.

     

    NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException 등이 λŒ€ν‘œμ μΈ Unchecked Exceptionμž…λ‹ˆλ‹€.

    λͺ…μ‹œμ μΈ μ˜ˆμ™Έ μ²˜λ¦¬λŠ” ν•„μˆ˜κ°€ μ•„λ‹ˆμ§€λ§Œ, ν”„λ‘œκ·Έλž¨μ˜ μ•ˆμ •μ„±μ„ μœ„ν•΄ μ€‘μš”ν•œ λΆ€λΆ„μ—μ„œλŠ” μ²˜λ¦¬ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

    public class UncheckedExceptionExample {
        public static void main(String[] args) {
            int[] numbers = {1, 2, 3};
            
            // μ˜ˆμ™Έ μ²˜λ¦¬κ°€ ν•„μˆ˜λŠ” μ•„λ‹ˆμ§€λ§Œ, ν”„λ‘œκ·Έλž¨μ˜ μ•ˆμ •μ„±μ„ μœ„ν•΄ μ²˜λ¦¬ν•˜λŠ” 것이 μ’‹μŒ
            try {
                System.out.println(numbers[5]);
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("λ°°μ—΄ 인덱슀 λ²”μœ„λ₯Ό λ²—μ–΄λ‚¬μŠ΅λ‹ˆλ‹€: " + e.getMessage());
            }
        }
    }

    πŸ“Œ 자주 μ‚¬μš©ν•˜λŠ” μ˜ˆμ™Έ 클래슀

    μ˜ˆμ™Έ 클래슀 μ„€λͺ…
    NullPointerException null 값을 μ°Έμ‘°ν•˜λ €κ³  ν•  λ•Œ
    ArrayIndexOutOfBoundsException λ°°μ—΄ μΈλ±μŠ€κ°€ λ²”μœ„λ₯Ό 벗어났을 λ•Œ
    IllegalArgumentException λ©”μ„œλ“œμ— 잘λͺ»λœ 인자λ₯Ό μ „λ‹¬ν–ˆμ„ λ•Œ
    NumberFormatException λ¬Έμžμ—΄μ„ 숫자둜 λ³€ν™˜ν•  λ•Œ ν˜•μ‹μ΄ λ§žμ§€ μ•Šμ„ λ•Œ
    IOException μž…μΆœλ ₯ μž‘μ—… 쀑 문제 λ°œμƒ μ‹œ (파일, λ„€νŠΈμ›Œν¬ λ“±)

    πŸ” try-catch-finally ꡬ쑰

    Javaμ—μ„œ μ˜ˆμ™Έλ₯Ό μ²˜λ¦¬ν•˜λŠ” κ°€μž₯ 기본적인 방법은 try-catch-finally 블둝을 μ‚¬μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

     

    기본 ꡬ쑰

    μ˜ˆμ™Έκ°€ λ°œμƒν•  수 μžˆλŠ” μ½”λ“œλ₯Ό try λΈ”λ‘μœΌλ‘œ 감싸고, λ°œμƒν•œ μ˜ˆμ™Έλ₯Ό catch λΈ”λ‘μ—μ„œ μ²˜λ¦¬ν•˜λ©°, finally λΈ”λ‘μ—μ„œλŠ” μ˜ˆμ™Έ λ°œμƒ 여뢀와 관계없이 항상 μ‹€ν–‰λ˜μ–΄μ•Ό ν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•©λ‹ˆλ‹€.

    try {
        // μ˜ˆμ™Έκ°€ λ°œμƒν•  수 μžˆλŠ” μ½”λ“œ
    } catch (μ˜ˆμ™Έν΄λž˜μŠ€ λ³€μˆ˜λͺ…) {
        // μ˜ˆμ™Έ λ°œμƒ μ‹œ 싀행될 μ½”λ“œ
    } finally {
        // μ˜ˆμ™Έ λ°œμƒ 여뢀와 상관없이 항상 μ‹€ν–‰
    }

     

    λ¨Όμ € try 블둝 λ‚΄μ˜ μ½”λ“œκ°€ μ‹€ν–‰λ˜λ©°, μ˜ˆμ™Έκ°€ λ°œμƒν•˜λ©΄ ν•΄λ‹Ή μ˜ˆμ™Έ νƒ€μž…μ— λ§žλŠ” catch λΈ”λ‘μœΌλ‘œ μ œμ–΄κ°€ μ΄λ™ν•©λ‹ˆλ‹€.

    μ—¬λŸ¬ catch 블둝이 μžˆλŠ” 경우, λ°œμƒν•œ μ˜ˆμ™Έ νƒ€μž…κ³Ό μΌμΉ˜ν•˜λŠ” 첫 번째 catch 블둝이 μ‹€ν–‰λ©λ‹ˆλ‹€.

    finally 블둝은 μ˜ˆμ™Έ λ°œμƒ 여뢀와 관계없이 항상 μ‹€ν–‰λ˜λ©°, try λ˜λŠ” catch λΈ”λ‘μ—μ„œ return 문이 μ‹€ν–‰λ˜μ–΄λ„ finally 블둝은 μ‹€ν–‰λ©λ‹ˆλ‹€.

     

    닀쀑 catchλ¬Έ

    λ‹€μ–‘ν•œ μœ ν˜•μ˜ μ˜ˆμ™Έλ₯Ό μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ μ—¬λŸ¬ catch 블둝을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    이 경우, μ˜ˆμ™Έ 계측 κ΅¬μ‘°μ—μ„œ μƒμœ„ 클래슀 μ˜ˆμ™ΈλŠ” ν•˜μœ„ 클래슀 μ˜ˆμ™Έ 뒀에 λ°°μΉ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

    κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ ν•˜μœ„ 클래슀 μ˜ˆμ™Έκ°€ μ²˜λ¦¬λ˜μ§€ μ•Šκ³  μƒμœ„ 클래슀 μ˜ˆμ™Έ μ²˜λ¦¬κΈ°μ— μ˜ν•΄ 포착될 수 μžˆμŠ΅λ‹ˆλ‹€.

    try {
        // μ˜ˆμ™Έ λ°œμƒ κ°€λŠ₯ μ½”λ“œ
    } catch (ArithmeticException e) {
        // ArithmeticException 처리
    } catch (NullPointerException e) {
        // NullPointerException 처리
    } catch (Exception e) {
        // λ‹€λ₯Έ λͺ¨λ“  μ˜ˆμ™Έ 처리
    }
    πŸ’‘ Java 7 μ΄μƒμ—μ„œλŠ” catch (A | B e) λ¬Έλ²•μœΌλ‘œ ν•˜λ‚˜μ˜ catch λΈ”λ‘μ—μ„œ μ—¬λŸ¬ μ˜ˆμ™Έ μ²˜λ¦¬λ„ κ°€λŠ₯ν•΄μš”!

     

    finally 블둝

    μ˜ˆμ™Έ λ°œμƒ 여뢀와 상관없이 무쑰건 μ‹€ν–‰λ˜λŠ” μ˜μ—­μž…λ‹ˆλ‹€. 

    주둜 νŒŒμΌ λ‹«κΈ°, DB μ—°κ²° ν•΄μ œ λ“± μžμ› 정리 μ½”λ“œμ— 주둜 μ‚¬μš©λ©λ‹ˆλ‹€.

    try {
        System.out.println("파일 μ—΄κΈ°");
    } catch (Exception e) {
        System.out.println("였λ₯˜ λ°œμƒ");
    } finally {
        System.out.println("μžμ› 정리");
    }

    πŸ™Œ 마무리

    이번 κΈ€μ—μ„œλŠ” Java μ˜ˆμ™Έ 처리의 기초 κ°œλ…μ„ μ€‘μ‹¬μœΌλ‘œ μ˜ˆμ™Έκ°€ 무엇이고, μ™œ μ²˜λ¦¬ν•΄μ•Ό ν•˜λŠ”μ§€, 그리고 try-catch-finally ꡬ쑰λ₯Ό μ–΄λ–»κ²Œ μ‚¬μš©ν•˜λŠ”μ§€ λ°°μ›Œλ΄€μŠ΅λ‹ˆλ‹€.

     

    μ˜ˆμ™Έ μ²˜λ¦¬λŠ” ν”„λ‘œκ·Έλž¨μ˜ μ•ˆμ •μ„±κ³Ό 신뒰성을 λ†’μ΄λŠ” μ€‘μš”ν•œ κΈ°μˆ μž…λ‹ˆλ‹€. μ μ ˆν•œ μ˜ˆμ™Έ 처리λ₯Ό 톡해 μ˜ˆμƒμΉ˜ λͺ»ν•œ μƒν™©μ—μ„œλ„ ν”„λ‘œκ·Έλž¨μ΄ μš°μ•„ν•˜κ²Œ μ²˜λ¦¬λ˜λ„λ‘ ν•΄μ•Ό ν•©λ‹ˆλ‹€.

     

    λ‹€μŒ κΈ€μ—μ„œλŠ” throw, throws와 μ‚¬μš©μž μ •μ˜ μ˜ˆμ™Έ 클래슀λ₯Ό 닀루며 μ˜ˆμ™Έλ₯Ό 직접 μ„€κ³„ν•˜κ³  μ œμ–΄ν•˜λŠ” 방법을 λ°°μ›Œλ³Ό μ˜ˆμ •μž…λ‹ˆλ‹€.

     

    κΆκΈˆν•œ λ‚΄μš©μ΄λ‚˜ μΆ”κ°€λ‘œ μ•Œκ³  싢은 κ°œλ…μ΄ μžˆλ‹€λ©΄ λŒ“κΈ€λ‘œ λ‚¨κ²¨μ£Όμ„Έμš” 😊

    λ°˜μ‘ν˜•