printStackTrace(), 멀티 catch블럭
printStackTrace()와 getMessage()
위의 메서드에 대해 알아보기 전에,
먼저 예외가 발생하면 어떤 일이 일어나는지 살펴보자.
try블럭을 실행하다가,
0으로 나누는 부분에서 예외가 발생한다.
그러면, 이때 예외 객체가 생성된다.
이 객체의 타입은 ArithmeticException 이다.
이 객체에는 발생한 예외대한 정보가 들어있다.
그리고, 이 객체는 앞으로 살펴볼, printStackTrace(), getMessage()와 같은 메서드들을 가지고 있다.
예외가 발생하면, 예외 객체가 생성되는데,
예외 객체에는 예외에 대한 정보가 들어있고,
그 정보들을 printStackTrace(), getMessage()같은 메서드를 통해서 가져올 수 있다.
예외가 발생되었을 때, 생성된 예외 객체의 타입과, catch블럭의 참조변수 타입과 일치하면
해당 catch블럭이 발생한 예외를 처리하게 된다.
해당 catch블럭의 참조변수 ae에 예외 객체의 주소가 저장된다.
해당 참조변수의 유효범위는 catch블럭이 끝날 때 까지이다.
해당 catch블럭 내에서는 해당 참조변수를 이용해서
예외에 의해 생성된 예외객체를 사용할 수 있다.
즉, 예외 객체에 담긴 예외 정보를 우리가 알 수 있다는 것이다.
그때 사용하는 것이 printStackTrace()메서드와, getMessage()라는 메서드가 있다.
printStackTrace()가 하는 일은,
호출 스택에 있는 정보를 화면에 출력해준다.
getMessage()는 발생한 예외의 메시지를 얻을 수 있다.
[Ex8_5]
예제를 보자.
1찍고, 2찍고, try블럭에 들어가서 3까지 출력하고,
0으로 나누는 부분에서 예외가 발생한다.
이떄 예외 객체가 생성된다.
그리고나서 catch블럭으로 가서 첫번째 catch블럭부터 살펴보는데,
이 예제에서는 첫번째 catch블럭과 타입이 일치한다.
그래서 참조변수 ae에 예외 객체의 주소가 저장된다.
참조변수 ae는 해당 catch블럭 내에서 사용 가능하다.
ae.printStackTrace();가 호출되어 출력된 것이,
이 예외 메시지이다.
ArithmeticException 예외가 발생했고, Ex8_5클래스의 main메서드, 그리고 파일의 8번째 줄에서 0으로 나눠서 발생했다는 내용을 담고있다.
호출스택을 그림으로 그려보면, main메서드가 있는데, 이것을 실행하다가 예외가 발생한 것이다. (예제의 호출스택을 표현)
printStackTrace();가 하는 일은, 예외발생 당시의 호출스택에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.
그리고 getMessage()를 이용해서 예외 메시지를 알 수 있다.
getMessage()가 반환하는 부분은 String이다.
그래서, System.out.println메서드로 ae.getMessage()를 찍은 것이다.
멀티 catch블럭
- 내용이 같은 catch블럭을 하나로 합친 것 (JDK 1.7 부터)
예를 들어서, catch블럭이 2개 있는데 내용이 같다.
이럴 때는 우측 코드처럼 하나의 catch블럭으로 바꿀 수 있다.
코드의 중복을 제거하기위해 노력하는 것이다.
이것이 바로 멀티 catch블럭이다.
두가지 주의사항이 있다.
- 멀티 catch블럭에 쓰는 두 클래스가 부모 자식관계이면 안된다.
안될 이유는 없지만, 이렇게 쓸 이유가 없다.
왜냐하면 catch블럭을 체크할 때, instanceof로 체크하기 때문이다.
즉, 발생한 예외와 꼭 일치하는 것을 처리하는 것이 아니라, 조상 타입의 참조변수가 선언되어 있는 catch블럭으로도 처리가 가능하다.
즉, 부모 타입의 참조변수가 선언된 catch블럭만 써주면 된다.
이를 어기면, compile에러가 난다.
- ExceptionA와 ExceptionB의 공통 멤버만 사용 가능
멀티 catch블럭의 경우, 어떤 A와 B중 어떤 경우의 예외가 발생해서 해당 멀티 catch문이 실행될지 모른다.
즉, 멀티 catch문에 선언된 참조변수가 예외 A객체를 가리키게 될지, 예외 B객체를 가리키게 될지 모른다.
이때, 만약 하나의 예외 타입에만 존재하는 메서드를 호출하면 에러가 발생하게 된다.
왜냐하면, 만약에 A타입의 예외객체에만 선언된 메서드를 멀티 catch문에서 호출해놓은경우,
발생된 예외가 B타입일 경우에는 A타입에만 선언된 메서드를 호출할 수 없기 때문이다.
따라서 멀티 catch문에는 예외객체들에 공통으로 선언되어있는 멤버만 호출이 가능하다.
그러나, 어쩔수 없이 객체별로 다르게 동작하게 하려면,
if else문을 사용해서 instanceof로 체크한 후, 형변환을 하면 호출할 수 있다.
(사실 이렇게 하면, 멀티 catch블럭을 사용하는 의미가 퇴색된다. 내용이 같을 때 사용하는게 멀티 catch블럭이기 때문이다.)
'JAVA' 카테고리의 다른 글
예외 선언하기, finally블럭 (0) | 2022.04.11 |
---|---|
예외 발생시키기, checked, unchecked 예외 (0) | 2022.04.11 |
예외 처리하기, try-catch문의 흐름 (0) | 2022.04.10 |
프로그램 오류, 예외 클래스의 계층구조 (0) | 2022.04.08 |
익명 클래스 (0) | 2022.04.08 |
댓글
이 글 공유하기
다른 글
-
예외 선언하기, finally블럭
예외 선언하기, finally블럭
2022.04.11 -
예외 발생시키기, checked, unchecked 예외
예외 발생시키기, checked, unchecked 예외
2022.04.11 -
예외 처리하기, try-catch문의 흐름
예외 처리하기, try-catch문의 흐름
2022.04.10 -
프로그램 오류, 예외 클래스의 계층구조
프로그램 오류, 예외 클래스의 계층구조
2022.04.08