[혼공자바] 6주차 공부 기록

Say·2025년 8월 24일
0

예외 처리

예외와 예외 클래스

  • 예외?

    • 프로그램 실행 중에 발생할 수 있는 오류 상황
    • 일반 예외와 실행 예외로 나뉨
  • 예외 클래스 구조

    • 모든 예외 클래스 ➡️ java.lang.Exception을 상속
    • 일반 예외
      • 프로그램 실행 시 발생 가능성이 높지 ❌
      • 보통 try-catch로 처리.
      • ex) ClassNotFoundException, InterruptedException
    • 실행 예외
      • 실행 중 예측 불가능하게 발생 ➡️ 컴파일러가 체크 ❌
      • ex) RuntimeException, NullPointerException, ClassCastException, NumberFormatException 등

실행 예외

  • 실행 예외
    • 개발자가 미리 예측, 처리하지 못하는 런타임(실행) 중의 오류
    • try-catch로 잡지 않으면 프로그램이 비정상 종료
    • 대표적 예외: NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException, NumberFormatException

✅ NullPointerException

  • 발생 상황
    • 참조 변수에 null이 들어가 있는데 그 객체의 메서드나 필드에 접근하려고 할 때!
String data = null;
System.out.println(data.toString());   // NullPointerException 발생!
// 결과: "Exception in thread 'main' java.lang.NullPointerException..."

✅ ArrayIndexOutOfBoundsException

  • 발생 상황
    • 배열의 인덱스 범위를 벗어나는 경우!
String[] arr = new String[3];
System.out.println(arr[3]);   // 0~2까지가 유효 인덱스, 3은 범위 벗어남
또는, main args 길이 조건이 안 맞을 때.

if(args.length == 2) {
  String data1 = args[0];
  String data2 = args[1];
  ...
} else {
  // args 인덱스 접근 불가.. ->  ArrayIndexOutOfBoundsException
}
// 결과: "Exception in thread 'main' java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds..."

✅ NumberFormatException

  • 발생 상황
    • 숫자로 변환 될 수 없는 문자열 데이터에 대해 Integer.parseInt() 혹은 Double.parseDouble() 등을 호출할 때!
String data1 = "100";
String data2 = "a100";
int value1 = Integer.parseInt(data1);    // ok
int value2 = Integer.parseInt(data2);    // NumberFormatException 발생!
결과: "Exception in thread 'main' java.lang.NumberFormatException: For input string: 'a100'..."

✅ ClassCastException

  • 발생 상황
    • 타입마다 맞는 객체만 캐스팅 해야 하는데, 실제 객체가 타입과 맞지 않을 때 강제 캐스팅 시 발생
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}

Dog dog = new Dog();
Cat cat = new Cat();

Dog d = (Dog) animal;   // animal이 Cat 타입이면 ClassCastException 발생!
안전하게 캐스팅 하려면 instanceof로 타입 체크 후 처리해야 한다.


if(animal instanceof Dog) {
  Dog d = (Dog) animal;
}

예외 처리(try-catch-finally)

  • 예외 처리의 목적

    • 예외가 발생해도 프로그램이 정상적으로 계속 동작할 수 있도록 작성하는 것
    • 자바는 예외 발생 시, 개발자가 직접 예외 처리 코드를 작성!
  • 예외 처리의 기본 코드

    • try-catch-finally 활용
try {
    // 예외 발생 가능 코드
} catch(예외클래스 e) {
    // 예외 발생 시 처리 코드
} finally {
    // 무조건 실행 코드 (자원 해제, 로그 등)
}
  • 일반 예외 처리 예시
public class TryCatchFinallyExample {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("java.lang.String2");
        } catch(ClassNotFoundException e) {
            System.out.println("클래스가 존재하지 않습니다.");
        }
    }
}

존재하지 않는 클래스명을 사용할 때 ClassNotFoundException 발생

실행 예외 처리

  • 실행 예외는 대부분 직접 코드를 작성해서 처리(컴파일러가 체크 ❌)
public class TryCatchFinallyRuntimeExceptionExample {
    public static void main(String[] args) {
        String data1 = null, data2 = null;
        try {
            data1 = args[0]; data2 = args[1];
        } catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("실행 매개값의 수가 부족합니다.");
            return;
        }

        try {
            int value1 = Integer.parseInt(data1);
            int value2 = Integer.parseInt(data2);
            int result = value1 + value2;
            System.out.println(data1 + " + " + data2 + " = " + result);
        } catch(NumberFormatException e) {
            System.out.println("숫자로 변환할 수 없습니다.");
        } finally {
            System.out.println("다시 실행해보세요.");
        }
    }
}
  • 매개값이 부족 ➡️ ArrayIndexOutOfBoundsException 처리
  • 숫자 변환 실패 ➡️ NumberFormatException 처리

다양한 예외에 따른 처리 코드 (다중 catch)

🤔 언제 쓸까나..?

  • 여러 예외를 따로따로 처리하고 싶을 때 → 다중 catch
try {
    // 코드
} catch(ArrayIndexOutOfBoundsException e) {
    // 배열 인덱스 오류 처리
} catch(NumberFormatException e) {
    // 숫자 변환 오류 처리
} finally {
    // 자원 해제 등
}
  • 발생하는 예외마다 각각 다른 catch 블록에서 별도 처리
  • 🚨 catch 블록 순서 주의!!
    • 상위 타입(Exception)을 먼저 catch하면 하위 타입(ArrayIndexOutOfBoundsException 등)은 도달 불가!

예외 떠넘기기 (throws 키워드)

  • 메소드 선언부에 throws 붙여 예외를 호출한 곳으로 넘기기
  • 직접 catch하지 ❌ ➡️ 호출한 메소드/클래스에게 예외 처리 책임을 넘김
  • 여러 예외를 throws 예외1, 예외2 처럼 지정 가능
    • 보통 한 번에 Exception으로 넘기기도..
리턴타입 메소드명(매개변수) throws 예외클래스1, 예외클래스2 { ... }

[숙제] throws에 대한 설명으로 틀린 것?!

① 생성자의 메소드 선언 끝 부분에 사용되어 메소드 내에서 발생될 예외를 떠넘긴다.
② throws 뒤에는 메서가 한 예외를 지정(,로 구분해서) 기술한다.
③ 모든 예외를 넘기기 위해 간단하게 throws Exception으로 작성할 수 있다.
④ 새로운 예외 발생시키기 위해 사용한다.

✅ throws의 역할!!
➡️ "이 메소드를 호출하는 곳에서 이 예외를 처리해야 해!" 라고 미리 명시하는 역할

④번은 오답이다!
"새로운 예외를 발생시키기 위해서 사용한다"고 했는데,
새로운 예외를 발생시키려면 throw(throw new ...)를 사용하기!

profile
Say Hi!

0개의 댓글