7일차(2) - 예외처리

은채의 성장통·2025년 6월 5일

KCC정보통신

목록 보기
10/30

노션 정리

Java 예외처리 (Exception Handling)

1. 개념 소개

예외처리는 프로그램 실행 중 발생할 수 있는 오류 상황에 적절히 대응하여 프로그램이 비정상 종료되지 않도록 도와주는 기술입니다.

💡 비유: 예외처리는 자동차의 에어백처럼, 사고(오류)가 나더라도 프로그램을 안전하게 보호해 줍니다.


2. 기본 구조: try ~ catch ~ finally

2.1 기본 try-catch 문

try {
    // 예외 가능성이 있는 코드
} catch (예외타입 변수명) {
    // 예외 발생 시 실행될 코드
}

예제: 배열 인덱스 예외 처리

Scanner scanner = new Scanner(System.in);
String[] greetings = {"안녕하세요.", "반갑습니다.", "또 오세요."};

while (true) {
    try {
        System.out.print("0 이상 " + greetings.length + " 미만의 정수를 입력하세요 (99는 종료): ");
        if (scanner.hasNextInt()) {
            int index = scanner.nextInt();
            if (index == 99) break;
            System.out.println(greetings[index]);
        } else {
            System.out.println("정수를 입력하세요.");
            scanner.next(); // 잘못된 입력 제거
        }
    } catch (Exception e) {
        System.out.println("⚠ 예외 발생: " + e.getMessage());
    }
}

2.2 finally 블록

finally는 예외 발생 여부와 관계없이 항상 실행되는 블록입니다.

try {
    // 예외 가능 코드
} catch (Exception e) {
    System.out.println("예외 발생");
} finally {
    System.out.println("항상 실행됩니다");
}

3. 다양한 예외 처리 방식

3.1 다중 catch

try {
    int result = divide(a, b);
} catch (ArithmeticException ae) {
    System.out.println("0으로 나누는 오류");
} catch (Exception e) {
    System.out.println("기타 예외");
}

3.2 멀티 캐치 (Java 7+)

catch (NullPointerException | IOException e) {
    System.out.println("예외 처리");
}

🔑 멀티 캐치는 서로 관련 없는 예외를 하나의 처리 블록으로 묶을 때 유용합니다.


4. 예외의 종류

4.1 Checked Exception (검사 예외)

  • 컴파일러가 예외 처리를 강제
  • 예: IOException, SQLException

4.2 Unchecked Exception (비검사 예외)

  • 런타임 시 발생, 예외 처리 선택 가능
  • 예: NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException

🔍 비유: Checked 예외는 신호등처럼 반드시 지켜야 하는 규칙, Unchecked 예외는 실수나 방심으로 인한 사고입니다.


5. 예외 던지기: throw vs throws

5.1 throws: 예외 알리기

메서드에서 예외가 발생할 수 있음을 호출자에게 알림

public static void printGreeting(int index) throws ArrayIndexOutOfBoundsException {
    System.out.println(greetings[index]);
}

5.2 throw: 예외 발생시키기

개발자가 명시적으로 예외 객체를 발생시킴

if (success == 0) {
    throw new ServerTimedOutException("서버 연결 실패", 80);
}

6. 사용자 정의 예외 클래스

개발자가 상황에 맞게 직접 예외 클래스를 정의하여 사용할 수 있습니다.

public class ServerTimedOutException extends Exception {
    private int port;

    public ServerTimedOutException(String message, int port) {
        super(message);
        this.port = port;
    }

    public int getPort() {
        return port;
    }
}

7. 오버라이딩 시 예외 선언

부모 클래스의 메서드를 오버라이딩할 때는 같거나 더 좁은 범위의 예외만 throws 가능합니다.

🔒 부모보다 더 위험한 예외를 던질 수는 없습니다.

예제 코드 시나리오

// FileSystem.java
import java.io.IOException;

public class FileSystem {
    public void save(int num) throws IOException {
        if (num < 0) {
            throw new IOException("num이 0보다 작습니다.");
        }
        System.out.println("File에 저장됐습니다.");
    }
}
// Super.java
import java.io.IOException;

public class Super {
    FileSystem fs = new FileSystem();

    public void doIt(int num) throws IOException {
        System.out.println("Super.doIt");
        fs.save(num);
    }
}
// Database.java
import java.sql.SQLException;

public class Database {
    public void insert(int num) throws SQLException {
        if (num > 100) {
            throw new SQLException("num이 너무 큽니다.");
        }
        System.out.println("데이터베이스에 저장되었습니다.");
    }
}
// Sub.java
import java.io.IOException;
import java.sql.SQLException;

public class Sub extends Super {
    Database db = new Database();

    @Override
    public void doIt(int num) throws IOException {
        System.out.println("Sub.doIt");
        try {
            db.insert(num);
        } catch (SQLException e) {
            throw new IOException(e.getMessage());
        }
    }
}
// ThrowsOverridingExample.java
import java.io.IOException;
import java.util.Random;

public class ThrowsOverridingExample {
    public static void main(String[] args) {
        Super[] works = new Super[2];
        works[0] = new Super();
        works[1] = new Sub();

        Random rand = new Random();
        int data = rand.nextInt(200);
        for (Super s : works) {
            try {
                s.doIt(data);
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }
}

🔁 Sub 클래스는 Super의 예외보다 더 넓은 SQLException을 throws할 수 없기 때문에, catch로 감싸고 IOException으로 변환합니다.


8. 요약 정리 ✍️

항목설명
try-catch-finally예외를 안전하게 처리하는 기본 구조
다중 catch / 멀티 캐치다양한 예외를 개별 또는 통합 처리 가능
Checked vs Unchecked컴파일러가 강제하는 예외 여부에 따른 분류
throw / throws예외를 직접 발생시키거나 전달하는 방식
사용자 정의 예외상황에 맞는 맞춤형 예외 처리
오버라이딩 시 예외 제한부모보다 더 넓은 예외는 throws할 수 없음

✅ 예외처리는 프로그램의 복원력을 높이는 핵심 기술입니다. 예외 상황을 예측하고 안전하게 처리함으로써 사용자 경험을 개선할 수 있습니다.

profile
인생 별거 없어

0개의 댓글