JAVA/이것이 자바다

이것이 자바다 | 10장 예외처리

한 면만 쓴 종이 2022. 7. 12. 17:38

10.1 예외와 예외 클래스

예외

  1. 일반 예외
  2. 실행 예외

일반예외(= 컴파일러 체크 예외) : 자바 소스를 컴파일하는 과정에서 예외 처리 코드가 없으면 컴파일 오류 발생

실행예외: 컴파일하는 과정에서 예외 처리 코드를 검사하지 않는 예외

 

일반예외 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()

: 예외 발생 코드를 추적해서 모두 콘솔에 출력