이것이 자바다 | 10장 예외처리
10.1 예외와 예외 클래스
예외
- 일반 예외
- 실행 예외
일반예외(= 컴파일러 체크 예외) : 자바 소스를 컴파일하는 과정에서 예외 처리 코드가 없으면 컴파일 오류 발생
실행예외: 컴파일하는 과정에서 예외 처리 코드를 검사하지 않는 예외
일반예외 vs 실행예외
일반예외: Exception을 상속받지만 Runtime Exception을 상속받지 않는 클래스
실행예외: RuntimeException을 상속받는 클래스
10.2 실행예외
1. NullPointerException
- 객체참조가 없는 상태 (= null값을 갖는 참조 변수로 객체 접근 연산자인 도트( . )를 사용할 경우 발생
2. ArrayIndexOutOfBoundsException
- 배열에서 인덱스 범위를 초과하여 사용할 경우 발생
3. NumberFormatException
Integer.parseInt(String s) // 문자열을 정수로 변환
Double.parseDouble(String s) // 문자열을 실수로 변환
- 숫자로 변환될 수 없는 문자가 포함되어 있다면 위 실행예외 발생시킴
4. ClassCastException
- 억지로 타입 변환을 시도할 경우 발생
타입 변환은 상위 클래스와 하위클래스, 구현 클래스와 인터페이스 간에 발생
10.3 예외 처리 코드
try - catch - finally 블록
finally 블록은 예외 발생 여부와 상관없이 항상 실행됨
- try, catch 블록에서 return 문을 사용해도 실행됨
10.4 예외 종류에 따른 처리 코드
1. catch 순서
다중 catch 블록을 작성할 때 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 함
2. 멀티 catch
하나의 catch 블록에서 여러 개의 예외를 처리할 수 있는 기능
catch괄호 안에 동일하게 처리하고 싶은 예외를 | 로 연결
try {
...
} catch(ArrayIndexOutOfBoundsException | NumberFormatException e) {
예외처리1
} catch(Exception e) {
예외처리2
}
10.5 자동 리소스 닫기
try - with - resources 사용시, 예외 발생 여부와 상관없이 사용했던 리소스 객체의 close() 메소드를 호출해서 안전하게 리소스를 닫아줌
try(FileInputStream fis = new FileInputStream("file.txt")) {
...
} catch(IOException e) {
...
}
try 블록이 정상적으로 실행을 완료했거나 도중에 예외가 발생하면 자동적으로 FileInputStream의 close() 메소드를 호출함
try{} 에서 예외가 발생하면 우선, close() 로 리소스를 닫고 catch 블록을 실행함
try - with - resources 사용 조건: 리소스 객체가 java.lang.AutoCloseable 인터페이스를 구현해야 함
// AutoCloseable 구현 클래스
public class FileInputStream implements AutoCloseable{
private String file;
public FileInputStream(String file) {
this.file = file;
}
public void read() {
System.out.println(file + "을 읽습니다.");
}
@Override
public void close() throws Exception {
System.out.println(file + "을 닫습니다.");
}
}
// AutoCloseable 구현 클래스
public class TryWithResourceExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("file.txt")) {
fis.read();
throw new Exception();
} catch(Exception e) {
System.out.println("예외 처리 코드가 실행되었습니다.");
}
}
}
10.6 예외 떠넘기기
: 메소드를 호출한 곳으로 예외 떠넘기기
리턴타입 메소드명(매개변수, ...) throws 예외클래스1, 예외클래스2, ... {
}
위의 방법이 일반적이지만 throws Exception만으로 모든 예외 떠넘기기 가능
리턴타입 메소드명(매개변수, ...) throws Exception {
}
10.7 사용자 정의 예외와 예외 발생
애플리케이션 예외(= 사용자 정의 예외) : 애플리케이션 서비스와 관련된 예외
일반 예외: Exception 상속
실행 예외: RunTimeException 상속
사용자 정의 예외의 이름은 Exception으로 끝나는 것이 좋음
10.8 예외 정보 얻기
모든 예외 객체들이 Exception을 상속하기 때문에 Exception의 모든 예외 객체 호출 가능
getMessage()
: 예외 메세지 얻기
printStackTrace()
: 예외 발생 코드를 추적해서 모두 콘솔에 출력