티스토리 뷰

JVM/JAVA

[JAVA] Exception에 대하여

글을 쓰는 개발자 2021. 11. 25. 18:47
반응형

Exception

1. 컴파일 에러

컴파일 시에 발생하는 에러

2. 런타임 에러

프로그램의 실행도중에 발생하는 에러

3. 논리적 에러

실행은 되지만, 의도와 다르게 동작하는 것

 

에러(error): 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
예외(exception): 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류

RuntimeException클래스들은 주로 프로그래머의 실수에 의해서 발생될 수 있는 예외들로 자바의 프로그래밍 요소들과 관계가 깊다.
Exception클래스들: 사용자의 실수와 같은 외적인 요인에 의해 발생되는 예외
RuntimeException클래스들: 프로그래머의 실수로 발생되는 예외
컴파일러가 예외처리를 확인하지 않는 RuntimeException클래스들은 'unchecked예외'라고 부르고, 예외처리를 확인하는 Exception클래스들은 'checked예외'라고 부른다.

 

try-with-resources문

try-with-resources문의 괄호()안에 객체를 생성하는 문장을 넣으면, 이 객체는 따로 close()를 호출하지 않아도 try블럭을 벗어나는 순간 자동적으로 close()가 호출된다. 
try(FileInputStream fis = new FileInputStream("score.dat");
	DataInputStream dis = new DataInputStream(fis)){
    //...
}

 

예외는 진짜 예외 상황에만 사용하라

javaEffective item69
예외는(그 이름이 말해주듯) 오직 예외 상황에서만 써야 한다. 절대로 일상적인 제어 흐름용으로 쓰여선 안 된다.
더 일반화해 이야기하면 표준적이고 쉽게 이해되는 관용구를 사용하고, 성능 개선을 목적으로 과하게 머리를 쓴 기법은 자제하라.
잘 설계된 API라면 클라이언트가 정상적인 제어 흐름에서 예외를 사용할 일이 없게 해야 한다.

추천!
Optional이나 특정값으로 표현하라

 

복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라

검사예외: 호출하는 쪽에서 복구하리라 여겨지는 상황이라면 검사 예외를 사용하라(checked예외)

API 설계자는 API 사용자에게 검사 예외를 던져주어 그 상황에서 회복하라고 요구/ 보통 좋지 않은 생각

비검사예외

런타임 예외/에러: 프로그래밍 오류를 나타낼 대는 런타임 예외를 사용하자(RuntimeException의 하위 클래스여야 한다.)

javaEffective item70
복구할 수 있는 상황이면 검사 예외를, 프로그래밍 오류라면 비검사 예외를 던지자. 확실하지 않다면 비검사 예외를 던지자. 검사 예외도 아니고 런타임 예외도 아닌 throwable은 정의하지도 말자. 검사 예외라면 복구에 필요한 정보를 알려주는 메소드도 제공하자.

 

필요 없는 검사 예외 사용은 피하라

1.
검사 예외를 회피하는 가장 쉬운 방법은 적절한 결과 타입을 담은 옵셔널을 반환하는 것이다.
검사 예외를 던지는 대신 단순히 빈 옵셔널을 반환하면 된다.

2.
검사 예외를 던지는 메서드를 2개로 쪼개 비검사 예외로 바꿀 수 있다. (예외가 던져질지 여부를 boolean값으로 반환한다.)
꼭 필요한 곳에만 사용한다면 검사 예외는 프로그램의 안전성을 높여주지만, 남용하면 쓰기 고통스러운 API를 낳는다. API가 호출자가 예외상황에서 복구할 방법이 없다면 비검사 예외를 던지자. 복구가 가능하고 호출자가 그 처리를  해주길 바란다면, 우선 옵셔널을 반환해도 될지 고민하자. 옵셔널만으로는 상황을 처리하기에 충분한 정보를 제공할 수 없을 때만 검사 예외를 던지자.

 

표준 예외를 사용하라

예외 주요 쓰임
IllegalArgumentException 허용하지 않는 값이 인수로 건네졌을 때(null은 따로 NullPointerException으로 처리)
IllegalStateException 객체가 메서드를 수행하기에 적절하지 않은 상태일 때
NullPointerException null을 허용하지 않는 메서드에 null을 건넸을 때
IndexOutOfBoundsException 인덱스가 범위를 넘어섰을 때
ConcurrentModificationException 허용하지 않는 동시 수정이 발견되었을 때
UnspportedOperationException 호출한 메서드를 지원하지 않을 때
Exception, RuntimeException, Throwable, Error는 직접 재사용하지 말자! 이 클래스들은 추상 클래스라고 생각하길 바란다

 

추상화 수준에 맞는 예외를 던져라

상위 계층에서는 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꿔 던져야 한다. (예외 번역[exception translation])
try{
	...// 저수준 추상화를 이용한다.
}catch(LowerLevelException e){
	throw new HighLevelException(...);
}
저수준 예외가 도움이 된다면 예외 연쇄(exception chaining)을 사용하는 것을 추천!(Throwable의 getCause 메서드를 통해 언제든지 꺼내 볼 수 있다.)
아래 계층의 예외를 예방하거나 스스로 처리할 수 없고, 그 예외를 상위 계층에 그대로 노출하기 곤란하다면 예외 번역을 사용하라. 이 때 예외 연쇄를 이용하면 상위 계층에는 맥락에 어울리는 고수준 예외를 던지면서 근본 원인도 함께 알려주어 오류를 분석하기에 좋다.

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함