티스토리 뷰

Java

9. 예외처리

kingsubin 2021. 1. 17. 22:28

목표

자바의 예외 처리에 대해 학습하세요.

학습할 것 (필수)

  • 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
  • 자바가 제공하는 예외 계층 구조
  • Exception과 Error의 차이는 ?
  • RuntimeException과 RE가 아닌것의 차이는 ?
  • 커스텀한 예외 만드는 방법

예외 처리 방법

 

Exception ?

- 런타임에 발생하는 원치 않거나 예기치 않은 이벤트로, 프로그램 명령의 정상적인 흐름을 방해하는 것

 

왜 Exception 이 발생하는가 ?

- 네트워크 연결문제, 잘못된 입력, 존재하지 않는 파일 열기 등 여러가지 이유로 인해 예외가 발생할 수 있다.

 

public static void exception1() {
    try {
    	// 예외가 일어날것같은 코드
    } catch (Exception e) {
    	// 예외시 처리할 코드
    } finally {
    	// 예외와 상관없이 항상 실행할 코드
        // try, catch 블록에서 return 문이 있더라도 실행됨
    }
}
public static void main(String[] args) {
    try {
        // 1을 0으로 나눴으므로 예외가 발생한다.
    System.out.println(1 / 0);
            
    } catch (IllegalArgumentException e) {
        System.out.println(e.getClass().getName());
        System.out.println(e.getMessage());
    } catch (ArithmeticException e) {
        System.out.println(e.getClass().getName());
        System.out.println(e.getMessage());
    } catch (NullPointerException e) {
        System.out.println(e.getClass().getName());
        System.out.println(e.getMessage());
    }
}

// java.lang.ArithmeticException
// / by zero

- catch block 이 여러개 있을 경우 예외 클래스의 인스턴스에 instanceof 연산자를 사용하여 검사한다.

- false 일 경우 다음 블록 이동, true 이면 해당 catch 블록 실행후 try-catch 문 탈출

- 만약 catch 문 안에서 해당 예외가 처리되지 않으면 프로그램 종료

 

public static void exception2() throws Exception {
    // 특정 조건 발생시
    throw new Exception();
}

- throws 는 해당 메서드에서 예외를 처리하지 않고, 해당 메서드를 사용하는 쪽이 예외를 처리하도록 전달하는 역할

 

try-with-resources Statement

- try block 에서 사용할 resource를 선언하는 식으로 사용

- finally block 대신에 resource를 자동으로 반환하기 위해 사용

- 여기서 말하는 리소스는 java.lang.AutoClosable 이나 java.io.Closable 을 구현한 오브젝트를 말하며 

 반드시 close 되야하는 리소스이다.

// Java 7 이전
static String beforeJava7(String path)
                                                     throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }
}

// Java 7 이후 try-with-resources
static String afterJava7(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

// Java 9 이후 try-with-resources
static String afterJava9(String path) throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    
    try (br) {
    	return br.readLine();
    }
}

예외 계층 구조

 

 

https://www.geeksforgeeks.org/exceptions-in-java/?ref=lbp

 


Exception vs Error

- 둘 다 최상위 예외 클래스인 Throwable 클래스의 하위 클래스

- Exception 은 개발자가 구현한 로직에서 발생

- Error 는 주로 시스템 레벨에서 발생

  - ex) 시스템 충돌 오류, 메모리 부족 오류

 


RuntimeException vs 아닌것 (Checked Exception)

- RuntimeException 은 Unchecked Exception 이어서 컴파일 단계에서 확인이 불가능,

 반면에 나머지 Exception은 컴파일 단계에서 확인이 가능하다.

 

Checked Exception

- IDE 가 코드내에서 표시해줌

- RuntimeException을 제외한 Exception을 상속받은 Exception

- 이런 예외는 예상할 수 있고 복구할 수 있음

- 즉, try-catch-finally 블록을 만들어야 함

 

Unchecked Exception

- 컴파일 단계에서 확인되지 않는 예외

- RuntimeException을 상속받은 Exception

- 일반적으로 발생을 예측할 수 없고 복구할 수없는 예외

- 주로 programming erros 나 외부 API 사용으로 인해 일어남

 


커스텀한 예외 만드는 방법

Checked Exception

- FileNotFoundException 의 경우 정확한 예외 원인을 알 수 없음

- 이름이 유효하지 않을 수 있고, 존재하지 않을 수도 있음

- java.lang.Exception 클래스를 상속받은 커스텀 클래스 만들어 해결

public class IncorrectFileNameException extends Exception { 
    public IncorrectFileNameException(String errorMessage) {
        super(errorMessage);
    }
    
    public IncorrectFileNameException(String errorMessage, Throwable err) {
    	super(errorMessage, err);
    }
}

- 예시 사용

try (Scanner file = new Scanner(new File(fileName))) {
    if (file.hasNextLine()) {
        return file.nextLine();
    }
} catch (FileNotFoundException err) {
    if (!isCorrectFileName(fileName)) {
        throw new IncorrectFileNameException(
          "Incorrect filename : " + fileName , err);
    }
    // ...
}

 

 

Unchecked Exception

- 파일 이름에 확장자가 없는 경우

- 런타임에서 감지되므로 Unchecked Exception 이며 사용자 정의 예외가 필요함

- java.lang.RuntimeException 클래스를 상속받은 커스텀 클래스 만들어 해결

public class IncorrectFileExtensionException 
  extends RuntimeException {
    public IncorrectFileExtensionException(String errorMessage, Throwable err) {
        super(errorMessage, err);
    }
}

- 예시 사용

try (Scanner file = new Scanner(new File(fileName))) {
    if (file.hasNextLine()) {
        return file.nextLine();
    } else {
        throw new IllegalArgumentException("Non readable file");
    }
} catch (FileNotFoundException err) {
    if (!isCorrectFileName(fileName)) {
        throw new IncorrectFileNameException(
          "Incorrect filename : " + fileName , err);
    }
    
    //...
} catch(IllegalArgumentException err) {
    if(!containsExtension(fileName)) {
        throw new IncorrectFileExtensionException(
          "Filename does not contain extension : " + fileName, err);
    }   
    //...
}

 

 

 


※ 출처

wisdom-and-record.tistory.com/46

velog.io/@youngerjesus/%EC%9E%90%EB%B0%94-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC

www.notion.so/cce3fc21976f4400aa4ed8d3fb26497b

www.geeksforgeeks.org/

 

 

※ 스터디

github.com/whiteship/live-study/issues/9

'Java' 카테고리의 다른 글

11. Enum  (0) 2021.01.29
10. 멀티쓰레드 프로그래밍  (0) 2021.01.27
8. 인터페이스  (0) 2021.01.09
7. 패키지  (0) 2021.01.02
6. 상속  (0) 2020.12.23