예외 구조와 종료

Exception ( CheckedException )

  • Exception 클래스를 직접 상속받는 모든 예외
  • RuntimeException을 상속받은 예외는 제외
  • 예외처리를 컴파일러가 확인 (빨간줄로 표시됨)

 

RuntimeException ( UncheckedException )

  • RuntimeException을 상속받는 모든 예외
  • 예외처리를 컴파일러가 확인하지 않음 (예외처리 강제 X)
  • 아주 사소한 예외 발생 가능성까지 CheckedException으로 예외 처리를 강제한다면, 개발 생산성이 저하되고 불필요한 코드가 많아질 수 있으므로 UncheckedException으로 자율적으로 예외 처리하도록 되어있는 시스템

 

예외 전파

: 메서드에서 발생한 예외가 해당 메서드 내에서 처리되지 않았을 때 메서드를 호출한 상위 메서드로 전달

  • 메인 메서드까지 예외가 전파되고, 그래도 처리 안되면 프로그램 비정상 종료

 

예외 처리 방법

  • `throw new 예외` 코드를 사용하면 의도적으로 예외를 발생시킬 수 있음 (프로그램이 더이상 실행되면 안되는 상황 일 때 사용)
  • try-catch-finally문으로 예외 처리 가능
  • `throws 예외` 코드를 사용하면 해당 메서드 안에서 발생하는 예외를 상위 메서드로 전달할 수 있음 (책임 전가)

 

의도한 예외 (throw)

public class Main {
    public static void main(String[] args) {
        int age = 10;
        if (age < 18) {
		        // ✅ 의도적으로 예외를 발생시키는 부분
            throw new IllegalArgumentException("미성년자는 접근할 수 없습니다!");
        }
        System.out.println("....");
    }
}

 

 

try-catch-finally문

try {
	// 예외가 발생할 가능성이 있는 실행문 작성
}
catch (예외 타입 선언) {
	// 예외 처리문 작성
}
finally {
	// 예외 발생 여부와 관계없이 무조건 실행될 코드 작성
}

 

try문을 실행하는 동안 catch문에 선언한 예외 타입에 해당하는 예외가 발견되면 catch문이 실행되고 마지막에 finally문이 실행된다. (finally문은 생략 가능)

만약 발생한 예외가 catch문에서 선언되지 않은 예외 타입인 경우는 예외 처리를 하지 않을 때와 마찬가지로 응용프로그램이 강제 종료된다.

다수의 예외를 처리하고자 하는 경우는 catch 블록 여러개를 연속적으로 작성할 수 있다.

 

 

예시. 3개의 정수를 입력받아 합을 구하는 프로그램을 작성하라. 사용자가 정수가 아닌 문자를 입력할 때 발생하는 InputMismatchException 예외를 처리하여 다시 입력받도록 하라.

import java.util.Scanner;
import java.util.InputMismatchException; //해당하는 예외 처리 패키지 임포트

public class InputException {
	public static void main(String[] args){
    	Scanner scanner = new Scanner(System.in);
        System.out.println("정수 3개를 입력하세요");
        
        int sum = 0, n = 0;
        for(int i=0; i<3; i++){
        	try{
            	n = scanner.nextInt();
            }
            catch(InputMismatchException e){
            	System.out.println("정수가 아닙니다. 다시 입력하세요!");
                scanner.nextLine(); // 현재 입력 스트림에 남아 있는 토큰을 지운다.
                i--; // 잘못 입력된 값으로 인해 인덱스가 증가하지 않도록 미리 감소
                continue; // 다음 루프 진행
            }
            
            sum += n;
        }
        System.out.println("합은 " + sum);
        scanner.close();
    }
}

 

 

상위 메서드로 예외 전달 (throws)

public class ExceptionPractice {

    public void callCheckedException() throws Exception { // ✅ throws 예외를 상위로 전파
        if (true) {
            System.out.println("체크예외 발생");
            throw new Exception();
        }
    }
}
package chapter3.exception;

public class Main {
    public static void main(String[] args) {

        // 예외 실습 객체 인스턴스화
        ExceptionPractice exceptionPractice = new ExceptionPractice();

        // 체크 예외 사용
        // ✅ 반드시 상위 메서드에서 try-catch 를 활용
        try {
            exceptionPractice.callCheckedException();
        } catch (Exception e) {
            System.out.println("예외처리");
        }
    }
}

 

 

 

커스텀 예외

  • 프로젝트에서 발생할 수 있는 특정한 오류를 처리하기 위해 자신만의 예외 클래스를 만드는 것
  • Exception, RuntimeException 중 하나를 상속하여 구현 가능

 

생성 방법

Exception 상속하는 경우 : 체크 예외이므로, 반드시 throws나 try-catch로 예외 처리해야 한다.

RuntimeException 상속하는 경우 : 언체크 예외이므로, 예외 처리를 강제하지 않음

 

// 체크 예외: 반드시 처리해야 하는 예외
// InvalidAgeException는 개인이 클래스에서 생성한 에러

public class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
}


public class Example {
    public static void setAge(int age) throws InvalidAgeException {
        if (age < 0) {
            throw new InvalidAgeException("나이는 음수가 될 수 없습니다!");
        }
    }

    public static void main(String[] args) {
        try {
            setAge(-1);
        } catch (InvalidAgeException e) {
            System.out.println(e.getMessage());  // 나이는 음수가 될 수 없습니다!
        }
    }
}
// 언체크 예외: 처리하지 않아도 되는 예외
// NegativeValueException는 개인이 클래스에서 생성한 예외

public class NegativeValueException extends RuntimeException {
    public NegativeValueException(String message) {
        super(message);
    }
}

public class Example {
    public static void setAge(int age) {
        if (age < 0) {
            throw new NegativeValueException("나이는 음수가 될 수 없습니다!");
        }
    }

    public static void main(String[] args) {
        setAge(-1);  // 예외 발생
    }
}

'언어, 프레임워크 > Java' 카테고리의 다른 글

접근 지정자 / final  (0) 2025.02.03
this() / 가비지 컬렉션  (1) 2025.02.03
배열  (0) 2025.01.31
비트 시프트 연산  (0) 2025.01.31
Java 알아보기  (0) 2025.01.21