표준 예외 클래스로도 많은 예외 상황을 표현할 수 있다. 하지만 그렇지 않은 경우도 있을 것이다. 이런 때는 직접 예외를 만들면 된다.
예외를 만들기 전에 해야 할 것은 자신의 예외를 checked로 할 것인가? unchecked로 할 것인가를 정해야 한다. 그 기준은 모호한 문제다. 하지만 기준이 없는 것도 아니다.
API 쪽에서 예외를 던졌을 때 API 사용자 쪽에서 예외 상황을 복구 할 수 있다면 checked 예외를 사용한다. checked 예외는 사용자에게 문제를 해결할 기회를 주는 것이면서 예외처리를 강제하는 것이다. 하지만 checked 예외를 너무 자주 사용하면 API 사용자를 몹시 힘들게 할 수 있기 때문에 적정선을 찾는 것이 중요하다.
사용자가 API의 사용방법을 어겨서 발생하는 문제거나 예외 상황이 이미 발생한 시점에서 그냥 프로그램을 종료하는 것이 덜 위험 할 때 unchecked를 사용한다. 기존의 ArithmeticException을 직접 만든 Exception으로 교체해보자.
package org.opentutorials.javatutorials.exception; class DivideException extends RuntimeException { DivideException(){ super(); } DivideException(String message){ super(message); } } class Calculator{ int left, right; public void setOprands(int left, int right){ this.left = left; this.right = right; } public void divide(){ if(this.right == 0){ throw new DivideException("0으로 나누는 것은 허용되지 않습니다."); } System.out.print(this.left/this.right); } } public class CalculatorDemo { public static void main(String[] args) { Calculator c1 = new Calculator(); c1.setOprands(10, 0); c1.divide(); } }
차이점
만약 DivideException을 Exception으로 바꾸면 어떻게 될까? 아래 코드의 RuntimeException을 Exception으로 변경하면 된다.
class DivideException extends RuntimeException {
class DivideException extends Exception {
아래와 같이 컴파일 에러가 발생한다.
src\org\opentutorials\javatutorials\exception\CalculatorDemo.java:18: error: unreported exception DivideException; must be caught or declared to be thrown throw new DivideException("0으로 나누는 것은 허용되지 않습니다."); ^ 1 error
이를 해결하려면 두가지 방법이 있다. 하나는 예외처리를 하는 것이다.
package org.opentutorials.javatutorials.exception; class DivideException extends Exception { DivideException(){ super(); } DivideException(String message){ super(message); } } class Calculator{ int left, right; public void setOprands(int left, int right){ this.left = left; this.right = right; } public void divide(){ if(this.right == 0){ try { throw new DivideException("0으로 나누는 것은 허용되지 않습니다."); } catch (DivideException e) { e.printStackTrace(); } } System.out.print(this.left/this.right); } } public class CalculatorDemo { public static void main(String[] args) { Calculator c1 = new Calculator(); c1.setOprands(10, 0); c1.divide(); } }
차이점
혹은 사용자에게 예외를 던진다. 사용자는 반드시 예외에 대한 처리를 해야 한다.
package org.opentutorials.javatutorials.exception; class DivideException extends Exception { DivideException(){ super(); } DivideException(String message){ super(message); } } class Calculator{ int left, right; public void setOprands(int left, int right){ this.left = left; this.right = right; } public void divide() throws DivideException{ if(this.right == 0){ throw new DivideException("0으로 나누는 것은 허용되지 않습니다."); } System.out.print(this.left/this.right); } } public class CalculatorDemo { public static void main(String[] args) { Calculator c1 = new Calculator(); c1.setOprands(10, 0); try { c1.divide(); } catch (DivideException e) { e.printStackTrace(); } } }
차이점
예외는 오류 없는 애플리케이션을 만들기 위해서 꼭 필요한 기능이다. 동기부여는 덜 되겠지만 꼭 숙지하길 바란다.