Item 69. Exceptional Conditions

μ˜ˆμ™ΈλŠ” μ§„μ§œ μ˜ˆμ™Έ μƒν™©μ—λ§Œ μ‚¬μš©ν•˜λΌ

μ œμ–΄ νλ¦„μ—μ„œμ˜ μ˜ˆμ™Έ

λ°˜λ³΅λ¬Έμ„ 순회 ν•  λ•Œ μ•„λž˜μ™€ 같이 μ˜ˆμ™Έλ₯Ό μ‚¬μš©ν•΄μ„œ 루프λ₯Ό μ’…λ£Œν•˜λŠ” 방법도 μ‘΄μž¬ν•  것이닀. JVM은 배열에 μ ‘κ·Όν•  λ•Œλ§ˆλ‹€ 경계λ₯Ό λ„˜μ§€ μ•ŠλŠ”μ§€ 검사λ₯Ό ν•˜λŠ”λ°, 1λ²ˆμ—μ„œλŠ” 쀑볡될 수 μžˆλŠ” λ°°μ—΄μ˜ 경계λ₯Ό λ„˜μ§€ μ•ŠλŠ”μ§€ κ²€μ‚¬ν•˜λŠ” λΆ€λΆ„(i < range.length)을 μ œκ±°ν–ˆλ‹€. λ•Œλ¬Έμ— 1번 방법이 루프λ₯Ό 더 λΉ λ₯΄κ²Œ 돌릴 수 μžˆλ‹€κ³  생각할 수 μžˆμ§€λ§Œ, μ‹€μ œλ‘œλŠ” 2번의 방법이 더 λΉ λ₯΄λ‹€.(μ•½ 2λ°° 차이)

class Test {

    public static void main(String[] args) {
        Mountain[] range = new Mountain[100000000];
        for (int i = 0; i < range.length; i++) {
            range[i] = new Mountain();
        }

        // 1. μ˜ˆμ™Έλ₯Ό μ¨μ„œ 루프 μ’…λ£Œ
        long start = System.currentTimeMillis();
        try {
            int i = 0;
            while (true) {
                range[i++].climb();
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            // ignore
        }
        long end = System.currentTimeMillis();
        System.out.println("μ‹€ν–‰ μ‹œκ°„ : " + (end - start) / 1000.0 + "초");

        // 2. for-each λ¬Έ μ‚¬μš©
        start = System.currentTimeMillis();
        for (Mountain mountain : range) {
            mountain.climb();
        }
        end = System.currentTimeMillis();
        System.out.println("μ‹€ν–‰ μ‹œκ°„ : " + (end - start) / 1000.0 + "초");
    }

    static class Mountain {

        public void climb() {
        }
    }
}

λ˜ν•œ 거의 λŒ€λΆ€λΆ„μ˜ μ‚¬λžŒλ“€μ΄ 직관적이지 μ•Šλ‹€λŠ” 이유둜 2번의 방법을 μ„ ν˜Έν•  κ²ƒμ΄μ§€λ§Œ, κ·Έ 이외에도 λ§Žμ€ μ΄μœ κ°€ μ‘΄μž¬ν•œλ‹€.

  1. μ˜ˆμ™ΈλŠ” μ˜ˆμ™Έ 상황을 λͺ©μ μœΌλ‘œ μ„€κ³„λ˜μ—ˆκΈ° λ•Œλ¬Έμ—, μ΅œμ ν™”λ˜μ–΄ μžˆμ§€ μ•Šλ‹€.(느린 속도)

  2. try-catch 블둝이 생기면 JVM이 μ μš©ν•  수 μžˆλŠ” μ΅œμ ν™”κ°€ μ œν•œλœλ‹€.

  3. 배열을 μˆœνšŒν•˜λŠ” ν‘œμ€€ κ΄€μš©κ΅¬μ—λŠ” 이미 μ΅œμ ν™” 처리 λ˜μ–΄ λ°°μ—΄ λ²”μœ„μ— λŒ€ν•œ 쀑볡 검사λ₯Ό μˆ˜ν–‰ν•˜μ§€ μ•ŠλŠ”λ‹€.

μ„±λŠ₯적인 μΈ‘λ©΄ 뿐만 μ•„λ‹ˆλΌ, μ•„λž˜μ™€ 같은 μ‹œλ‚˜λ¦¬μ˜€λ‘œ 인해 μ œλŒ€λ‘œ λ™μž‘ν•˜μ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€.

  1. 반볡문 μ•ˆμ— 버그가 μ‘΄μž¬ν•œλ‹€κ³  κ°€μ •

  2. 흐름 μ œμ–΄μ— μ‚¬μš©λœ μ˜ˆμ™Έκ°€ ν•΄λ‹Ή 버그λ₯Ό μˆ¨κΉ€

  3. λ°˜λ³΅λ¬Έμ—μ„œ ν˜ΈμΆœν•œ λ©”μ„œλ“œκ°€ κ΄€λ ¨ μ—†λŠ” 배열을 μ‚¬μš© 쀑에 ArrayIndexOutOfBoundsException을 던짐

  4. ν‘œμ€€ κ΄€μš©κ΅¬λΌλ©΄ 이 λ²„κ·ΈλŠ” μ˜ˆμ™Έλ₯Ό μž‘μ§€ μ•Šκ³  μŠ€λ ˆλ“œκ°€ μ’…λ£Œλ˜μ§€λ§Œ, μ˜ˆμ™Έλ₯Ό μž‘μ•˜κΈ° λ•Œλ¬Έμ— μŠ€λ ˆλ“œλŠ” μ’…λ£Œλ˜μ§€ μ•Šκ³  계속 싀행됨

μœ„ μƒν™©μ²˜λŸΌ ν˜λŸ¬κ°„λ‹€λ©΄ μ˜λ„μΉ˜ μ•Šμ€ λ™μž‘μœΌλ‘œ 인해 디버깅이 더 μ–΄λ €μ›Œμ§€κ³ , μ‹¬κ°ν•œ 논리적 였λ₯˜κ°€ λ°œμƒν•  수 μžˆλ‹€. λ•Œλ¬Έμ— μ˜ˆμ™ΈλŠ” μ˜ˆμ™Έ μƒν™©μ—μ„œλ§Œ μ‚¬μš©ν•΄μ•Όν•˜λ©°, μ œμ–΄ νλ¦„μš©μœΌλ‘œλŠ” μ‚¬μš©ν•˜μ§€ 말아야 ν•œλ‹€.

μƒνƒœ 검사λ₯Ό ν†΅ν•œ μ˜ˆμ™Έ 처리 μ΅œμ†Œν™”

μ˜ˆμ™Έλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³ , μƒνƒœ 검사λ₯Ό 톡해 μ˜ˆμ™Έ 처리λ₯Ό μ΅œμ†Œν™” ν•  수 μžˆλ‹€. 잘 μ„€κ³„λœ APIμ—μ„œλŠ”, ν΄λΌμ΄μ–ΈνŠΈκ°€ 정상적인 μ œμ–΄ νλ¦„μ—μ„œ μ˜ˆμ™Έλ₯Ό μ‚¬μš©ν•  일이 μ—†κ²Œ ν•΄μ€€λ‹€.

import java.util.Iterator;

class Test {
    public static void main(String[] args) {
        // 1. hasNext()λ₯Ό ν†΅ν•œ μƒνƒœ 검사
        for (Iterator<Foo> i = collection.iterator(); i.hasNext(); ) {
            Foo foo = i.next();
            // do something
        }

        // 2. μ˜ˆμ™Έ 처리λ₯Ό ν†΅ν•œ μƒνƒœ 검사
        try {
            Iterator<Foo> i = collection.iterator();
            while (true) {
                Foo foo = i.next();
                // do something
            }
        } catch (NoSuchElementException e) {
            // ignore
        }
    }
}

Iterator μΈν„°νŽ˜μ΄μŠ€μ˜ next() λ©”μ„œλ“œλŠ” λ‹€μŒ μš”μ†Œκ°€ μ‘΄μž¬ν•˜μ§€ μ•Šμ„ λ•Œ NoSuchElementException을 λ˜μ§€λŠ”λ°, μ‚¬μš©ν•˜κΈ° 전에 hasNext() λ©”μ„œλ“œλ₯Ό 톡해 λ‹€μŒ μš”μ†Œκ°€ μ‘΄μž¬ν•˜λŠ”μ§€ ν™•μΈν•˜κ³  μ‚¬μš©ν•˜λ©΄ μ˜ˆμ™Έλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³ λ„ μƒνƒœ 검사λ₯Ό ν•  수 μžˆλ‹€.

μƒνƒœ 검사 λ©”μ„œλ“œ vs Optional vs νŠΉμ • κ°’

μƒνƒœ 검사 λ©”μ„œλ“œ λŒ€μ‹  Optional을 μ‚¬μš©ν•˜κ±°λ‚˜ null 같은 νŠΉμˆ˜ν•œ 값을 λ°˜ν™˜ν•˜λŠ” 방법도 μ‘΄μž¬ν•˜λŠ”λ°, μ…‹ 쀑 μ„ νƒν•˜λŠ” 방법은 지침은 μ•„λž˜μ™€ κ°™λ‹€.

  1. Optional / νŠΉμ • κ°’

    • μ™ΈλΆ€ 동기화 없이 μ—¬λŸ¬ μŠ€λ ˆλ“œκ°€ λ™μ‹œ μ ‘κ·Όν•˜κ±°λ‚˜ μ™ΈλΆ€ μš”μΈμœΌλ‘œ λ³€ν•˜λŠ” 경우: μƒνƒœ 검사 λ©”μ„œλ“œμ™€ μƒνƒœ 의쑴적 λ©”μ„œλ“œ 호좜 사이에 객체 μƒνƒœκ°€ λ³€ν•  수 있기 λ•Œλ¬Έμ— Optional / νŠΉμ • 값이 μ ν•©ν•˜λ‹€.

    • μ„±λŠ₯이 μ€‘μš”ν•œ 상황: μƒνƒœ 검사 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 것보닀 Optional / νŠΉμ • 값을 μ‚¬μš©ν•˜λŠ” 것이 더 λΉ λ₯΄λ‹€.

  2. μƒνƒœ 검사 λ©”μ„œλ“œ

    • λ‹€λ₯Έ λͺ¨λ“  경우: 가독성이 살짝 더 μ’‹κ³ , 잘λͺ» μ‚¬μš©ν–ˆμ„ λ•Œ 디버깅이 더 쉽닀.

Last updated

Was this helpful?