본문 바로가기
Application/Java

[Jump2Java] 07장 예외 처리

by 윤루트 2021. 9. 16.
  • 예외처리를 위한 try, catch문의 기본 구조
try {
    ...
} catch(예외1) {
    ...
} catch(예외2) {
    ...
...
}
  • try 문 안의 문장들을 수행 중 해당하는 예외가 발생하면 예외에 해당되는 catch문이 수행된다.
  • 숫자를 0으로 나누었을 때 발생하는 예외를 처리하려면 다음과 같이 할 수 있다.
int c;
try {
    c = 4 / 0;
}catch(ArithmeticException e) {
    c = -1;
}
  • ArithmeticException 이 발생하면 c에 -1을 대입하도록 예외처리한 것이다.
    • 0으로 나누었을 때 에러 발생 문구가 ArithmeticException 이다.

finally 구문

  • 떤 예외가 발생하더라도 반드시 실행되어야 하는 부분이 있다면 해당 부분을 fianlly 구문으로 감싸준다.
public class Test {
    public void shouldBeRun() {
        System.out.println("ok thanks.");
    }

    public static void main(String[] args) {
        Test test = new Test();
        int c;
        try {
            c = 4 / 0;
        } catch (ArithmeticException e) {
            c = -1;
        } finally {
            test.shouldBeRun();    // shouldBeRun 이라는 무조건 실행해야 하는 임의의 메소드이다.
        }
				System.out.println(c);
    }

/* 출력 결과
ok thanks
-1
*/
  • try 구문에서 0으로 나누었기 때문에 ArithmeticException 에러가 난다.
  • 이때 catch로 ArithmeticException 에러가 나는 경우 c 에 -1 을 저장한다.
  • 프로그램을 끝내기 전 finally 구문이 있으므로 test.shouldBeRun 메소드를 실행한다.
    • "ok thanks" 가 출력된다.
    • c는 -1이 담겨있으므로 -1이 출력된다.
  • Exception은 크게 두가지로 구분된다.
    1. RuntimeException (Unchecked Exception)
      1. 실행 시 발생하는 예외
      2. 발생 할수도 발생 안 할수도 있는 경우에 작성
    2. Exception (Checked Exception)
      1. 컴파일 시 발생하는 예외
      2. 프로그램 작성 시 이미 예측가능한 예외를 작성할 때 사용
    • 예시 - fool 이라고 입력값으로 sayNick 메소드 실행 시 예외 처리
    public class FoolException extends Exception {
    	public class Test {
    	    public void sayNick(String nick) {
    	        try {
    	            if("fool".equals(nick)) {
    	                throw new FoolException();
    	            }
    	            System.out.println("당신의 별명은 "+nick+" 입니다.");
    	        }catch(FoolException e) {
    	            System.err.println("FoolException이 발생했습니다.");
    	        }
    	    }
    	
    	    public static void main(String[] args) {
    	        Test test = new Test();
    	        test.sayNick("fool");
    	        test.sayNick("genious");
    	    }
    	}
    }​

    • try에서 만약 fool이 들어왔다면, FoolException() 으로 예외 처리를 한다.
    • catch 문에 의해 에러에 대한 출력으로 대체하여 정상적으로 컴파일한다.
    • 즉, 예외 처리 발생 시킨 후 예외 처리를 한 것이다.
    • 이렇게 하지 않고 sayNick을 호출한 곳에서 FoolException을 처리하도록 예외를 위로 던질 수 있는 방법이 있다.
    public void sayNick(String nick) throws FoolException {
        if("fool".equals(nick)) {
            throw new FoolException();
        }
        System.out.println("당신의 별명은 "+nick+" 입니다.");
    }
    
    public static void main(String[] args) {
        Test test = new Test();
        try {
            test.sayNick("fool");
            test.sayNick("genious");
        }catch(FoolException e) {
            System.err.println("FoolException이 발생했습니다.");
        }
    }​

    • sayNick 메소드 뒷부분에 throws 라는 구문을 이용하여 FoolException을 위로 보낼 수가 있다. ("예외를 뒤로 미루기"라고도 한다.)
    • throws 구문 때문에 FoolException의 예외를 처리해야 하는 대상이 sayNick 메소드에서 main 메소드(sayNick 메소드를 호출하는 메소드)로 변경되었다.
    • 그러므로 main 메소드를 위와 같이 수정한다.
    • sayNick 메소드에서 처리 vs main 메소드에서 처리
    • sayNick 메소드에서 예외를 처리하는 경우에는 다음의 두 문장이 모두 수행이된다.
    test.sayNick("fool");
    test.sayNick("genious");​

    • main 메소드에서 다음과 같이 예외 처리를 한 경우에는 두번 째 문장인 test.sayNick("genious");가 수행되지 않을 것이다. 이미 첫번 째 문장에서 예외가 발생하여 catch 문으로 빠져버리기 때문이다.
    try {
        test.sayNick("fool");
        test.sayNick("genious");
    }catch(FoolException e) {
        System.err.println("FoolException이 발생했습니다.");
    }​

댓글