Exception?
- 자바에서 예외는 우리가 예상한, 혹은 예상치 못한 일이 발생하는 것을 미리 예견하고 안전장치를 하는 것 을 말합니다.
- 예외가 발생되는 일반적인 예
- null인 객체에 메소드를 호출한다든지(null인 list에 get() 을 호출)
- 5개의 공간을 가지는 배열을 만들었는데 6번째 값을 읽으려 한다던지
- 네트워크 연결이 되어 잇는 서버가 갑자기 작동을 멈춰서 연결이 끊겨버리는 경우
Error VS Exception
- 위 그림처럼 Error가 발생되면 프로세스(프로그램이 메모리에 올라간 상태)가 중단되며
- Exception이 발생되면 쓰레드가 중단됩니다.
CheckedException
- CheckedException은 잘 작성된 애플리케이션이 예외 발생전에 미리 예상하고 복구해야하는 예외 조건 입니다.( 컴파일 타임 시에 처리 됨)
- CheckedException의 대표적인 경우로 FileNotFoundException이 있습니다.
- FileNotFoundException은 사용자가 읽어오고자 하는 File이름을 제대로 입력하지 않았을 때 발생하는 예외 입니다
Unchecked Exception
프로그램의 로직상에서 발생한 문제를 통해 Unchecked Exception이 발생합니다.
private static void divideByZero() {
int numerator = 1;
int denominator = 0;
int result = numerator / denominator;
}
위 코드와 같이 0으로 숫자를 나눌려고 할때, 자바 프로그램은 ArithmeticException 을 발생시킵니다.
💡 자바는 unChecked Exception을 컴파일시에 확인하지 않습니다. 또한 unchecked Excetpion을 throws 키워드를 통해 예외를 선언할 필요가 없습니다.
ArithmeticException 과 같은 unchecked exception들은 runtime시에 exception을 throw 합니다.
또한 unchecked exception의 부모 exception은 RuntimeException입니다.
언제 checked / unchecked exception 을 쓸까?
- 오라클 자바 공식 문서에서는 다음과 같이 checked/unchecked exception을 써야되는 상황을 말해주고 있습니다.
클라이언트가 예외로부터 복구될 수 있다고 예상할수 있는 경우 Checked Exception을 선택합니다. 반면 클라이언트가 예외로부터 복구될 수 없는 경우 UnChecked Exception으로 지정합니다.
예를 들어, 파일을 열기전에 우리는 열고자 하는 파일의 이름을 Validation할 수 있습니다.
만약 유저가 입력한 파일이름이 존재하지 않는다면 우리는 custom checked exception을 발생시킬 수 있습니다.
if(!isCorrectFileName(fileName)){
throw new IncorrectFileNameException("InCorrect FileName: "+fileName);
}
이런 방식으로, 사용자에게 다른 입력 파일 이름을 입력하도록 유도함으로써 시스템을 복구할 수 있습니다.
그러나 사용자가 정상적으로 입력했는데도 파일 이름이 null pointer 거나 비어있는 문자열인 경우, 코드상에 문제가 있다는 뜻입니다. 이러한 경우에는 unchecked exception을 발생시켜야 합니다.
if (fileName == null || fileName.isEmpty()) {
throw new NullOrEmptyException("The filename is null or empty.");
}
👍 추가 팁
Try - with -resource & Multiple Catch Block
package exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.FileSystemNotFoundException;
public class ExceptionSample {
public static void main(String[] args) {
Integer test = null;
try (FileInputStream file = new FileInputStream("ExceptionSample.java")) {
file.read();
} catch (FileSystemNotFoundException | FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
}
위 코드와 같이 Try-with-Resource를 통해 AutoCloseable 인터페이스를 구현한 클래스에 한해 해당 클래스의 자원을 반환하는 close() 메서드를 명시해주지 않아도 된다.
또한 Multiple Catch Block을 통해 같은 관계(IOException 은 상위 두 Exception의 부모 Exception이기 때문에 따로 catch 해주었습니다.)에 있는 Exception들을 한 문장에서 처리함으로써 Code의 가독성을 높일 수 있습니다.
참고
https://blog.devgenius.io/5-best-practices-to-handle-exceptions-in-java-5e1534f83772
https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
'프로그래밍 > Java' 카테고리의 다른 글
Singleton 패턴과 스프링에서는 Singleton 패턴을 어떻게 사용하고 있을까? (0) | 2023.01.27 |
---|---|
Long 과 AtomicLong은 어떤 차이가 있을까? (0) | 2023.01.24 |
ConcurrentHashMap은 어떻게 동시성 문제를 해결할까? (0) | 2023.01.24 |
Java Thread Pool? (0) | 2022.12.28 |
Eclipse(이클립스) 단축키 Mac용 (0) | 2021.07.07 |