[Java] 예외처리

thingzoo·2023년 6월 16일
0

Java

목록 보기
12/20
post-thumbnail

오류 vs 예외

오류(error)

일반적으로 회복이 불가능한 문제

  • 컴파일 에러: 컴파일할때 발생하는 에러
  • 런타임 에러: 실행할때 발생하는 에러
  • 논리적 에러: 의도와 다르게 동작하는 에러

예외(exception)

일반적으로 회복이 가능한 문제

코드 실행 관점

  • 컴파일 에러(예외): 문법에 맞게 작성하면 해결
  • 런타임 에러(예외): 실행할 때 발생하는 에러(예외)

예외처리 관점

  • 확인된 예외(Checked Exception)
    • 컴파일 시점에 확인되는 예외
    • 반드시 예외 처리 해줘야 함
  • 미확인된 예외(Unchecked Exception)
    • 런타임 시점에 확인되는 예외
    • 예외 처리 필수는 아님

예외 발생과 try-catch, finally문

확인된 예외를 처리해보자

예외처리의 흐름

1. 예외클래스 정의

class OurException extends Exception {
	public OurException() {
		super("예외처리입니다!");
	}
}

2. 메소드에 예외 발생 알림(throws/throw)

class OurClass {
    private final Boolean just = true;
    public void thisMethodIsDangerous() throws OurException {
        if (just) {
            throw new OurException();
        }
    }
}
  • throws
    • 메소드 이름 뒤에 붙어 이 메소드가 어떤 예외사항을 던질 수 있는지 알려주는 예약어
    • 메소드(...) + throws + 예외클래스
  • throw
    • 메소드 안에서 실제로 예외 객체를 던질 때 사용하는 예약어
    • 메소드를 종료 시킴
    • throw+new 예외클래스();

3. 예외 처리(try-catch, finally)

public class StudyException {
    public static void main(String[] args) {
        OurClass ourClass = new OurClass();

        try {
            // 1. 예외 발생 가능성 있는 메소드를 시도하는 블럭
            ourClass.thisMethodIsDangerous();
        } catch (OurException e) {
            // 2. 예외 잡고 처리하는 블럭
            System.out.println(e.getMessage());
        } finally {
            // 3. 무조건 실행되는 블럭
            System.out.println("예외처리했습니다!");
        }

    }
}

예외 클래스 구조

Trowable Class

문제 상황을 뜻하는 클래스

RuntimeException을 상속한 예외들은 UncheckedException, 그렇지 않은 예외들은 CheckedException으로 구현됨

에러 구현체들

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

연결된 예외(Chained Exception)

  • 예외는 다른 예외를 유발 할 수 있음
  • 예외 A가 예외 B를 발생시켰다면, 예외 A는 B의 원인 예외
  • 원인 예외를 새로운 예외에 등록한 후 다시 새로운 예외를 발생시키는 것을 예외 연결이라고 함

원인 예외를 다루기 위한 메소드

  • 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: 진짜 예외이유

실제 예외 처리하는 방법 3가지

예외 복구

public String getDataFromAnotherServer(String dataPath) {
		try {
				return anotherServerClient.getData(dataPath).toString();
		} catch (GetDataException e) {
				return defaultData;
		}
}
  • 실제로 try-catch로 예외를 처리하고 프로그램을 정상 상태로 복구하는 방법
  • 가장 기본적인 방식이지만, 현실적으로 복구가 가능한 상황이 아닌 경우가 많거나 최소한의 대응만 가능한 경우가 많기 때문에 자주 사용되지는 않음

예외 처리 회피

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

public void someIrresponsibleMethod() throws Exception {
		this.someMethod();
}
  • 관심사를 분리해서 한 레이어에서 처리하기 위해서 이렇게 에러를 회피해서 그대로 흘러 보내는 경우

예외 전환

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

public void someResponsibleMethod() throws MoreSpecificException {
		try {
			this.someMethod();
		} catch (IOException e) {
			throw new MoreSpecificException(e.getMessage());
		}
}
  • 예외처리 회피하기의 방법과 비슷하지만, 조금더 적절한 예외를 던져주는 경우
  • 보통은 예외처리에 더 신경쓰고싶은 경우나, 오히려 RuntimeException처럼 일괄적으로 처리하기 편한 예외로 바꿔서 던지고 싶은 경우 사용

Reference

🔗 스파르타코딩클럽 Java 문법 종합반
🔗 자바의 정석

profile
공부한 내용은 바로바로 기록하자!

0개의 댓글