[프로그래머스 자바 입문] 예외(Exception)-3
예외 회피하기(throws)
- throws는 예외가 발생했을 때, 예외를 호출한 쪽에서 처리하도록 던져준다.
-
메소드 선언부에 throws 키워드를 사용하여 해당 메소드를 사용할 때 발생할 수 있는 예외를 미리 명시할 수 있다.
-
ex) 정수 2개를 매개변수로 받아 나눗셈한 결과를 반환하는 divide 메소드. main 메소드에서는 divide 메소드를 호출한다.
public class ExceptionExam2 [ public static void main(String[] args) { int i = 10; int j = 0; int k = divide(i, j); System.out.println(k); } public static int divide(int i, int j) { int k = i / j; // ArithmeticException 발생(0으로 나눌 수 없음) return k; } }
- 위의 divide 메소드를 수정하여, divide 메소드에서 발생하는 ArithmeticException을 호출하는 쪽에서 처리하도록 한다.
-
divide 메소드를 호출하는 main 메소드에서 예외를 처리하도록 코드를 수정한다.
public class ExceptionExam2 [ public static void main(String[] args) { int i = 10; int j = 0; try { // 예외 발생 메소드 호출 int k = divide(i, j); System.out.println(k); } catch(ArithmeticException e) { // 호출하는 쪽에서 예외 처리 System.out.println("0으로 나눌 수 없습니다."); } } // ArithmeticException 발생 메소드. 예외를 호출한 쪽으로 넘긴다. public static int divide(int i, int j) throws ArithmeticException { int k = i / j; return k; } }
- 💡 Exception 클래스는 모든 예외 클래스의 조상이므로
throws Exception
을 하면, 해당 메소드 내에서 발생하는 모든 예외를 모두 넘길 수 있다.
- 💡 Exception 클래스는 모든 예외 클래스의 조상이므로
예외 발생시키기(throw)
- throw 키워드를 사용하여 강제로 예외를 발생시킬 수 있다.
-
오류를 떠넘기는 throws와 주로 같이 사용된다.
public class ExceptionExam3 { public static void main(String[] args) { int i = 10; int j = 0; try { // 예외 발생 메소드 호출 int k = divide(i, j); System.out.println(k); } catch(ArithmeticException e) { // 호출하는 쪽에서 예외 처리 System.out.println("0으로 나눌 수 없습니다."); } } // 예외를 호출한 쪽으로 넘긴다. public static int divide(int i, int j) throws IllegalArgumentException { // **2번째 매개변수가 0으로 전달될 경우 강제로 예외를 발생시킨다. if(j == 0) { throw new IllegalArgumentException("0으로 나눌 수 없어요."); } int k = i / j; return k; } }
- 0으로 잘못된 나누기를 하여 ArithmeticException을 발생시키기 전에, 두 번째 매개변수가 0이 아닌지 먼저 확인해 예외 처리하려 한다.
- j가 0일 경우 new 연산자를 통하여 IllegalArgumentException 객체를 만들고, throw 키워드로 강제로 예외를 발생시킨다.
- 예외가 발생하면, throws 키워드로 해당 예외를 호출한 쪽으로 넘긴다.
사용자 정의 예외 클래스
- Exception이나 Exception의 후손 클래스를 상속받아 자신만의 새로운 예외 클래스를 정의하여 사용할 수 있다.
- 클래스의 이름만으로 어떤 오류가 발생했는지 알려주어 코드의 직관성을 높일 수 있다.
-
사용자 정의 예외 클래스에는 생성자뿐만 아니라 필드 및 메소드도 원하는 만큼 추가할 수 있다.
- 사용자 정의 예외 클래스는 다음과 같이 2가지로 나눌 수 있다.
- Exception 클래스를 상속받아 정의한 checked Exception
- 반드시 오류를 처리해야만 하는 Exception
- RuntimeException 클래스를 상속받아 정의한 unChecked Exception
- 예외 처리를 하지 않아도 컴파일 시 오류를 발생시키지 않는다.
- Exception 클래스를 상속받아 정의한 checked Exception
- ex) RuntimeException을 상속받은 사용자 정의 예외 클래스 RuntimeException
- 부모 클래스인 RuntimeException에 이미 같은 기능을 가지는 생성자가 있기 때문에, 매개변수로 받아들인 값을 부모 생성자에게 전달해주기만 하면 된다.
- 비즈니스 로직이 수행될 때 발생하는 예외에 대한 클래스
public class BizException extends RuntimeException { // 문자열 오류메시지를 받는 생성자 (4) public BizException(String msg) { // 부모 생성자에게 메세지를 넘김 super(msg); } // 실제 발생한 예외를 받는 생성자 public BizException(Exception ex) { // 부모 생성자에게 예외 를 넘김 super(ex); } }
- ex) 업무 처리 메소드를 가진 BizService 클래스
- 사용자 정의 예외를 발생시키는 BizException를 사용.
- 업무와 관련하여 예외가 발생했음을 호출한 곳에 알린다.
public class BizService { // BizExcepton 예외를 호출한 곳으로 넘긴다. (5) public void bizMethod(int i) throws BizExcepton { System.out.println("비지니스 로직이 시작합니다."); // (2) if(i < 0) { // 예외를 발생시킨다 (3) throw new BizException("매개변수 i는 0이상이어야 합니다."); } System.out.println("비지니스 로직이 종료됩니다."); } }
-
ex) 앞에서 만든 BizService를 이용하는 BizExam 클래스
public class BizExam { public staic void main(String[] args) { BizService biz = new BizService(); biz.bizMethod(5); try { // 메소드 호출. 예외를 발생시키는 인자 전달 (1) biz.bizMethod(-3); // 메소드를 호출한 곳에서 예외 처리 (6) } catch(Exception ex) { ex.printStackTrace(); } } }
-
실행 결과
비지니스 로직이 시작합니다. 비지니스 로직이 종료됩니다. 비지니스 로직이 시작합니다. javaStudy.BizException: 매개변수 i는 0이상이어야 합니다. at javaStudy.BizService.bizMethod(BizService.java:7) at javaStudy.BizExam.main(BizExam.java:9)