[whiteship] 9주차 - 예외처리

prayme·2021년 1월 16일
0
post-thumbnail

학습할 것 (필수)

  • 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
  • 자바가 제공하는 예외 계층 구조
  • Exception과 Error의 차이는?
  • RuntimeException과 RE가 아닌 것의 차이는?
  • 커스텀한 예외 만드는 방법

자바 예외 처리

try/catch/finally

자바에서는 서로 다른 두가지 방싱의 exception handling 메커니즘을 가진다. 전통적인 방식은 try/catch/finally 구문이다.
tryexception handling을 위한 코드를 항상 시작시킨다(establishe). trycatch구문을 0개 이상 동반한다.
동반되는 각각의 catch는 하나 이상의 서로 다른 exception을 처리할 수 있다. 여러개의 Exception을 처리할 때는 |을 통해 구분하자. 항상 Throwable의 하위 클래스를 캐치할 수 있다. Exception이 발생했을 때 발생한 타입에 맞는 catch문을 찾는다.
finalllytry가 발생하면 무조건 실행되는 구문이다. catch와 마찬가지로 생략되어도 상관없다. 대부분 try에서 시도한 코드들을 수습할 때 사용한다고 한다.

문법을 살펴보자

try {

}
catch (SomeException e1) {

}
catch (AnotherException | YetAnother Exception e2) {

}
finally {

}

try with resources

문법부터 보자

try (InputStream is = new FileInputStream("/Users/ben/details.txt")) {

}

try의 괄호 안에는 cleanup이 필요한 모든 객체가 파라미터로 들어올 수 있다. 파라미터로 들어온 객체는 try 블록에서만 스코프를 지닌다. 블록이 끝나면 자동으로 cleanup된다. ~~python의 with 같은 녀석인가봄~~

좋은 녀석이라고 하니까 자주 사용합시다.

자바가 제공하는 예외 계층 구조

자바 예외 핸들링은 checked, unchecked 2가지 타입의 예외로 나뉜다.

두 타입의 차이점은 예외가 throw를 해줘야하는가 아닌가에 달렸다.

Checked Exception

checked exception은 상당히 구체적인 상황에서 발생한다.
어플리케이션이 예외로부터 부분적으로나 완전하게 타격을 받지 않을 수 있다.

예를들어, 여러 개의 디렉토리 중 하나에서 설정 파일을 찾아야하는 코드를 작성 했을 때 존재하지 않는 디렉토리에 접근을 시도하면 FileNotFoundExceptionthrow 된다.

우리는 방금 발생한 FileNotFoundExceptioncatch하고 다음 디렉토리로 이동하고 싶을 것이다.
즉, 파일이 존재하지 않는 예외는 충분히 예상 가능하고 있을 법한 예외이며 치명적이지 않기 때문에 타격을 받지 않고 다음 동작으로 넘어갈 수 있다는 뜻이다.

checked exception의 경우 예상 가능하기 때문에 우리가 직접 try/catch문으로 예외를 핸들링해줘야만한다.

Unchecked Exception

checked exception과는 다르게 런타임 조건과 라이브러리 코드의 남발로 쉽게 예측할 수 없는 에러들이 존재한다.
예를들어 OutOfMemoryErrorNullPointerException 같은 경우에는 쉽게 예측할 수 없다. 사용자가 어떤 입력 값을 입력할지는 모르는 법이고 배열이나 객체를 사용하는 모든 메소드들은 Null을 넘겨줄 수 있기 때문이다.

이런 것들을 unchecked exception이라고 하고 언제든지 어떤 메소드던지간에 unchecked exception을 던질 수 있다.

uncheckedcheckedThrowable 객체이며 Error, Exception 중 하나의 서브클래스이다.

uncheckedError 객체의 서브 클래스이다. 또한 RuntimeException 객체의 서브클래스이기도 한다.
그 외를 제외한 모든 exception 들은 checked exception이다.

Error와 Exception의 차이

Error는 컴파일 오류, 스택오버플로우, 메모리 부족, Null과 같이 복구하기가 어려운 치명적인 상황을 말한다.
Error는 개발자가 미리 예측할 수가 없고 설사 예측하더라도 복구하기 어려운 문제이기 때문에 try/catch등으로 해결하려고 노력하지 말자.

Exception은 위의 예시와 같이 파일 탐색 프로그램이 접근하고자하는 파일이 존재하지 않을 때처럼 치명적이지 않은 상황을 말한다.

따라서 Exceptiontry/catch로 프로그램이 의도와 다르게 종료되지 않도록 처리를 해줘야한다.

Scanner sc = new Scanner(System.in);
int[] arr = {0, 1}; # 배열의 길이는 2
try {
	for (int i=0; i<2; i++) {
	        # 1이상의 숫자를 입력 시 ArrayIndexOutOfBoundsException 발생
		System.out.println(arr[sc.nextInt()]); 
        	
	}
} catch (ArrayIndexOutOfBoundsException e) {
	e.printStackTrace();
}

System.out.println("Gotcha!!");

Runtime Exception vs 아닌 것

Runtime Exception 은 언제든지 발생할 수 있는 예외이다. 이러한 예외들은 버그가 발생하지 않으면 버그가 없으므로 일일이 throws를 작성할 필요가 없다.
오히려 RuntimeExceptioncatch를 하지 않는 것이 바람직할 수 있다. 치명적인 오류이기 때문에 프로그램을 종료시키는 것이 최선의 방책이라고 할 수 있다.

그렇지 않은 것들은 충분히 예상이 가능하기 때문에 예외처리를 통해 프로그램이 종료되는 것을 방지해야한다.

Custom Exception

Exception을 상속받은 클래스를 정의하면 된다.
정의한 클래스를 try/catch 문에서 throw하면 동작까지 완성이다.

# 내가 정의한 Exception
public class MyException extends Exception {
    public MyException() {
        super();
    }

    public void printError() {
        System.out.println("MyError 발동!");
    }
}

...
...

try {
  if (hasError()) {
    throw new MyException();
  }
} catch (MyException e) {
  e.printError();
}
profile
잘하고 싶은 사람

0개의 댓글