-
예외 처리(Exception)language/JAVA 2019. 1. 23. 13:42반응형
자바 컴파일러는 어떤 위험 요소 때문에 프로그램에 문제가 생기는 것을 원하지 않습니다.
그렇기 때문에 자바 프로그래머는
그래서 위험 요소가 있는 메소드를 호출할 때 만약의 경우에 어떻게 행동할 지를 미리 알려줘야 합니다.
그러기 위해서는 호출하는 메소드의 위험요소에 대해 알고 있어야 하고
위험하다는 것을 인지하고 나면 만약을 대비해 실패했을 경우 그 실패 상황을 처리할 수 있는 코드를 만들어야 합니다.
컴파일러는 예외적인 상황이 발생하는 것을 싫어합니다.
하지만 위험한 코드를 try/catch 문으로 포장해 주면 컴파일러는 아무 불평도 하지 않습니다.
try/catch 블록은 호출할 메소드에서 예외와 관련된 일이 일어날 수 있다는 것을 알고 있고, 그에 대한 대비가 되어 있음을 알려주는 역할을 합니다.
컴파일러는 어떤 식으로 대비하는지 구체적인 방법에는 신경쓰지 않고 예외를 처리할 것이라는 사실에만 신경씁니다.
try/catch 구문을 실제 코드를 통해서 살펴보도록 하겠습니다.
sleep 이라는 메서드는 예외가 발생할 수 있는 메서드 입니다. 그 사실은 API 문서를 통해서 확인할 수 있습니다.
이런 메서드를 호출할 때는 try/catch 문으로 감싸줘야 합니다.
예외가 발생하면 발생한 예외를 잡아서 처리하는 코드를 넣습니다. 지금 이 catch 문에서는 해당하는 예외를 잡아서 그 예외의 결과를 출력하게 됩니다.
컴파일러는 예외를 어떻게 처리하는가는 신경쓰지 않기 때문에 이렇게만 해줘도 컴파일이 됩니다. (catch 문 아래 e는 인자와 마찬가지)
이 때 알아야 할 것이 예외는 Exception이라는 유형의 객체라는 점 입니다.
앞의 코드에서 catch문이 잡았던 것도 객체이고 sleep method가 던진 것도 객체입니다.
객체이기 때문에 객체로서 특징을 가지고 있습니다.
상속에 대해서 설명할 때 상속을 통해 다형성을 구현할 수 있다고 했는데
예외 역시 객체이기 때문에 마찬가지로 다형성을 활용할 수 있습니다.
다시말해 Exception이 위와같은 상속트리를 가지고 있다고 했을 때
GirlsException이나 BoysException 객체를 상위의 Exception 유형을 통해 다형적으로 참조할 수 있습니다.
실제로 예외클래스의 상속트리를 살펴보면 위와 같습니다. 모든 클래스의 최상위 클래스인 Object를 확장한 Throwable 클래스가 있고 그 Throwable 클래스를 확장한 Error 클래스와 Exception 클래스가 있습니다.
에러와 예외의 차이는 예외는 발생할 상황을 미리 예측하여 대비할 수 있다는 것입니다. 즉 개발자가 작성하는 로직에서 발생하는 것이 예외입니다. (제가 코딩 하면서 에러를 자주 보지 못한 것 같습니다, OutOfMemory, StackOverflow)
Exception은 수많은 자식 클래스를 가지고 있습니다. 그 중에서 RuntimeException은 조금 다른 특징을 가지고 있습니다.
RuntimeException은 CheckedException과 UncheckedException을 구분하는 기준입니다. Exception의 자식 클래스 중 RuntimeException을 제외한 모든 클래스는 CheckedException이며, RuntimeException과 그의 자식 클래스들을 Unchecked Exception이라 부릅니다. CheckedException과 UncheckedException에 대해 더 자세히 살펴보도록 하겠습니다.
Checked Exception 과 Unchecked Exception의 가장 큰 차이는 예외처리를 반드시 해야하느냐 아니냐 입니다.
Unchecked Exception은 RuntimeException의 하위 클래스에 속하는 예외인데 이름처럼 실행단계에서 예외를 확인할 수 있습니다.
예를들어 NullPointerException 이나 IndexOutOfBoundException 같은 경우 컴파일러에서는 예외 발생 여부를 확인하기 어렵습니다.
그렇기 때문에 컴파일러는 RuntimeException에서 예외처리를 강제하지 않는 것입니다. (illegalargumentexception 부적절한 상태, 부적절한 문자열을 숫자로 바꾼다던지, 쓰레드 상태가 적합하지 않다던지)
다시 예외의 상속트리로 돌아와서 실제 try/catch 문에 사용되는 모습을 살펴보겠습니다.
그림에서처럼 CoffeeException이 TeaException을 확장하고 TeaException이 Exception을 확장하는 상속 트리를 생각해 봅시다
그럼 오른쪽 코드와 같은 try/catch 문을 사용할 수 있습니다.
이렇게 여러가지 예외에 대해 처리를 할 때 기억해야 할 것은
상속트리에서 하위에 위치하는 예외를 먼저 처리해야 한다는 것입니다.
try/catch 문에서는 무조건 첫번째 블록부터 순서대로 처리하기 때문에 상위 객체에 대한 처리를 먼저 나열하면 적절한 예외를 잡지 못하고 놓쳐버리게 됩니다.
꼭 해당 위험한 메소드를 호출한 곳에서 예외를 처리할 필요는 없습니다.
예외처리를 해야하는 메소드에서 예외를 던지게 되면 메소드를 던진 그 메소드를 호출한 메소드에서 예외를 잡아서 처리할 수 있습니다.
이 방법을 통해 예전에 썼던 코드를 이렇게 바꿀 수 있습니다.
이렇게 예외에 대해서 알아봤습니다.
반응형'language > JAVA' 카테고리의 다른 글
serialization(직렬화) (0) 2019.01.23 GUI / innerclass(내부클래스) (0) 2019.01.23 정적 변수, 정적 메소드(static) (0) 2019.01.23 자바에서 변수를 다루는 법 (0) 2019.01.17 상속(Inheritance)의 개념 (1) 2019.01.17