-
목표
자바의 예외 처리에 대해 학습하세요.
학습할 것 (필수)
- 자바에서 예외 처리 방법 (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(); } }
예외 계층 구조
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
※ 스터디