Java Exception
업데이트:
Error
- 런타임 시, 시스템 혹은 가상머신에서 비정상적인 상황으로 인해서 발생하는 심각한 수준의 오류이다.
- 개발자가 사전에 예측하여 처리할 수 없기 때문에, 오류에 대한 처리를 신경쓰지 않아도 된다.
- 대표적으로 StackOverflowError, OutOfMemoryError 등이 존재한다.
Exception
- 런타임 시, 개발자가 잘못 구현한 로직(코드) 혹은 사용자의 잘못된 조작에서 발생하는 오류이다.
- 개발자가 사전에 예측하여 처리할 수 있기 때문에, 예외를 구분하여 그에 맞는 대처를 할 수 있다.
- 대표적으로 IOException, NullPointerException 등이 존재한다.
Checked Exception & Unchecked Exception
Checked Exception | Unchecked Exception | |
---|---|---|
예외 처리 | 명시적 예외 처리 | 생략 가능 |
확인 시점 | 컴파일 단계 | 런타임 단계 |
예외 발생 시, 트랜잭션 처리 | Rollback 수행 | Rollback 미수행 |
대표 예외 | Exception 클래스의 자식(서브) 클래스 | RuntimeException 클래스의 자식(서브) 클래스 |
IOException | RuntimeException | |
SQLException | NullPointerException | |
InterruptedException | ClassCastException |
예외 처리
방법
예외 복구
- 예외 상황을 파악하고 문제를 해결해서 정상 상태로 돌려놓는 방법이다.
- 재시도를 통해 복구하는 방법이 있다.
예외처리 회피
- 예외 처리를 직접 담당하지 않고, 호출한 쪽으로 던져 회피하는 방법이다.
- throws 키워드를 이용하여 예외를 전달하는 방법이 있다.
예외 전환
- 예외 회피와 비슷하게 메서드 밖으로 예외를 던지지만, 그냥 던지지 않고 적절한 예외로 전환해서 넘기는 방법이다.
- 사용자 정의 Exception을 생성하여 해당 클래스로 throws 키워드를 이용하여 전달하는 방법이 있다.
핸들링
try ~ catch block
- try ~ catch 블록을 이용하여 예외가 발생하는 부분을 감싸고 예외가 발생하면, 적절한 방법으로 처리한다.
public class FileService {
public List<String> usingTryCatch() {
List<String> rows = new ArrayList<>();
// You must declare the InputStreamReader, BufferedReader class outside the try~catch syntax so it can be used and closed.
InputStreamReader inputStreamReader = new InputStreamReader(FileService.class.getClassLoader().getResourceAsStream("music.txt"));
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
rows.add(line);
}
return rows;
} catch (IOException e) {
e.printStackTrace();
} finally { // Must close the InputStreamReader, BufferedReader class.
try {
inputStreamReader.close();
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public List<String> usingTryWithResources() {
List<String> rows = new ArrayList<>();
try (InputStreamReader inputStreamReader = new InputStreamReader(FileService.class.getClassLoader().getResourceAsStream("music.txt"));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);) {
String line;
while ((line = bufferedReader.readLine()) != null) {
rows.add(line);
}
return rows;
} catch (IOException e) {
e.printStackTrace();
} // Even if you don't use the Finally keyword, the BufferedReader closes automatically.
return null;
}
}
- usingTryCatch 메서드의 경우 InputStreamReader와 BufferedReader를 종료하는 close() 메서드를 호출하기 위해서 finally 구문을 사용해야 하는데 scope의 문제로 try~catch 구문 밖에 변수를 선언하여야 사용하는 불편함이 존재한다.
- usingTryWithResources 메서드의 경우 JDK 1.7부터 지원하는 try-with-resources 구문을 사용하여 소괄호 안에 정의한 변수들은 AutoCloseable 인터페이스를 상속받아 구현되어 있어, 구문 종료 이후 자동으로 리소스 관리를 해준다.
throws
- 메서드 내부에서 발생하는 Exception을 호출한 메서드로 전달한다.
- 예외처리 회피에 사용되는 방법이다.
public class FileService {
...
public List<String> usingThrows() throws IOException { // Pass the IOException to the caller.
List<String> rows = new ArrayList<>();
try (InputStreamReader inputStreamReader = new InputStreamReader(FileService.class.getClassLoader().getResourceAsStream("music.txt"));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
rows.add(line);
}
return rows;
}
}
}
throw
- 메서드 내부에서 발생하는 Exception을 적절한 Exception으로 전환하여 호출한 메서드로 전달한다.
- 예외 전환에 사용되는 방법이다.
public class FileException extends RuntimeException {
private static final long serialVersionUID = -7903712172617310856L;
public FileException(String message) {
super(message);
}
public FileException(Throwable cause) {
super(cause);
}
public FileException(String message, Throwable cause) {
super(message, cause);
}
}
public class FileService {
...
public List<String> usingThrow() { // Pass the IOException to the caller.
List<String> rows = new ArrayList<>();
try (InputStreamReader inputStreamReader = new InputStreamReader(FileService.class.getClassLoader().getResourceAsStream("music.txt"));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
rows.add(line);
}
return rows;
} catch (IOException e) {
throw new FileException("An error occurred while loading the file.", e);
}
}
}
※ Sample Code는 여기에서 확인 가능합니다.
댓글남기기