본문 바로가기
[스파르타코딩클럽]/Java 문법 종합반

Chapter 10. 예외처리

by 진진리 2023. 10. 17.
728x90
  • 오류(Error): 일반적으로 회복이 불가능한 문제
    • 시스템 레벨에서, 또는 주로 환경적인 이유로 발생
    • 에러가 발생한 경우 어떠한 에러로 프로그램이 종료되었는지 확인하고 대응
  • 예외(Exception): 일반적으로 회복이 가능한 문제
    • 코드레벨에서 할 수 있는 문제상황에 대한 대응은 "예외처리"에 속함
  • 예외의 종류
    1. 코드실행 관점에서
      • 컴파일: 프로그래밍 언어로 작성한 코드를 컴퓨터가 이해할 수 있는 언어로 변환하는 것(.java -> .class)
      • 컴파일 에러: 언어의 규칙을 지키지 않아서 발생. 문법에 맞게 다시 작성
      • 런타임 에러: 컴파일은 잘 되었지만 프로그램 실행 도중 발생
    2. 예외처리 관점에서
      • 확인된 예외(Checked Exception): 컴파일 시점에 확인하는 예외. 반드시 예외 처리를 해야함.
      • 미확인된 예외(Unchecked Exception): 런타임 시점에 확인되는 예외. 예외 처리가 반드시 필요하지 않음.

 


예외처리의 흐름

  • 예외 정의하기: 예외 클래스를 만들어 에러를 정의
class OurBadException extends Exception {
	public OurBadException() {
		super("위험한 행동을 하면 예외처리를 꼭 해야합니다!");
	}
}
  • 클래스 내의 메서드가 위험하다고 알리기: throw, throws
    • throws: 메서드 이름 뒤에 붙어 이 메서드가 어떤 예외사항을 던질 수 있는지 알려주는 예약어
    • throw: 메서드 안에서 실제로 예외 객체를 던질 때 사용하는 예약어
      • 실제로 던지는 예외 객체 하나와 같이 사용해야 함
      • throw 아래의 구문들은 실행되지 않고 throw문과 함께 메서드가 종료됨
class OurClass {
    private final Boolean just = true;
		
    public void thisMethodIsDangerous() throws OurBadException {
        if (just) {
            throw new OurBadException();
        }
    }
}
  • 위험한 메서드를 사용할 때 예외를 handling: try-catch, finally 문
    • 1개의 try문에 여러개의 catch문 사용 가능
    • throws로 위험한 메서드임을 알렸으니 이 메서드를 사용할 때 예외처리를 하지 않으면 컴파일 에러 발생
public class StudyException {
    public static void main(String[] args) {
        OurClass ourClass = new OurClass();

        try {
            // 1. 위험한 메소드의 실행을 "시도" 해 봅니다.
            // "시도" 해보는 코드가 들어가는 블럭입니다.
            ourClass.thisMethodIsDangerous();
        } catch (OurBadException e) {
            // 2. 예외가 발생하면, "잡아서" handling 합니다.
            // 예외가 발생하는경우 "handling" 하는 코드가 들어가는 블럭입니다.
			// 즉 try 블럭 내의 구문을 실행하다가 예외가 발생하면
			// 예외가 발생한 줄에서 바로 코드 실행을 멈추고
			// 여기 있는 catch 블럭 내의 코드가 실행됩니다.
            System.out.println(e.getMessage());
        } finally {
            // 3. 예외의 발생 여부와 상관없이, 실행시켜야 하는 코드가 들어갑니다.
            // 무조건 실행되는 코드가 들어가는 블럭입니다.
            System.out.println("우리는 방금 예외를 handling 했습니다!");
        }

    }
}

자바의 Throwable Class


Chained Exception, 실제 예외 처리하는 방법

  • 연결된 예외(Chained Exception)
    • 예외는 다른 예외를 유발
    • 원인 예외를 새로운 예외에 등록한 후 다시 새로운 예외를 발생시키는데 이를 예외 연결이라고 함
    • 예외를 연결하는 이유:
      1. 여러 가지 예외를 큰 분류의 예외로 묶어서 다루기 위해서
      2. checked exception을 unchecked exception으로 포장하는데 사용
  • 원인 예외를 다루기 위한 메소드
    • initCause(): 지정된 예외를 원인 예외로 등록하는 메소드
    • getCause(): 원인 예외를 반환하는 메소드
// 연결된 예외 
public class main {

    public static void main(String[] args) {
        try {
            // 예외 생성
            NumberFormatException ex = new NumberFormatException("가짜 예외이유");

            // 원인 예외 설정(지정한 예외를 원인 예외로 등록)
            ex.initCause(new NullPointerException("진짜 예외이유"));

            // 예외를 직접 던집니다.
            throw ex;
        } catch (NumberFormatException ex) {
            // 예외 로그 출력
            ex.printStackTrace();
            // 예외 원인 조회 후 출력
            ex.getCause().printStackTrace();
        }

        // checked exception 을 감싸서 unchecked exception 안에 넣습니다.
        throw new RuntimeException(new Exception("이것이 진짜 예외 이유 입니다."));
    }
}

// 출력
Caused by: java.lang.NullPointerException: 진짜 예외이유

 

  • 실제로 예외 처리하기

1. 예외 복구: 최소한의 대응만 가능한 경우가 많아 자주 사용되지는 않음

public String getDataFromAnotherServer(String dataPath) {
	try {
		return anotherServerClient.getData(dataPath).toString();
	} catch (GetDataException e) {
		return defaultData;
	}
}

2. 예외 처리 회피

public void someMethod() throws Exception { ... }

public void someIrresponsibleMethod() throws Exception {
	this.someMethod();
}

someMethod()에서 발생한 에러가 someIrresponsibleMethod()의 throw를 통해 흘러나감

 

3. 예외 전환

public void someMethod() throws IOException { ... }

public void someResponsibleMethod() throws MoreSpecificException {
	try {
		this.someMethod();
	} catch (IOException e) {
		throw new MoreSpecificException(e.getMessage());
	}
}

someMethod()의 예외가 잡히면 조금더 적절한 예외를 다시 throw

'[스파르타코딩클럽] > Java 문법 종합반' 카테고리의 다른 글

Chapter 12. 스레드  (0) 2023.10.18
Chapter 11. 제네릭(Generic)  (0) 2023.10.17
Chapter 9. 인터페이스  (0) 2023.10.17
Chapter 8. 상속  (0) 2023.10.16
Chapter 7. 클래스  (0) 2023.10.16