오늘 수업시간에 '예외처리'와 관련하여 배웠습니다. 이때까지 미션을 진행해오면서 이에 관한 깊은 이해없이 예외처리를 사용해왔었는데요. 오늘 Pair 프로그래밍에서 주어진 미션들을 해결해 나가면서 여러모로 많은 것들을 배울 수 있는 시간이었습니다. 미션 순서대로 하나씩 정리하면서 개념도 추가적으로 설명하겠습니다.
미션1. PointTest에서 Point에 대한 exception테스트를 추가한다.
- x, y 값이 0미만, 24초과에 대한 에러 테스트를 추가한다.
첫번째 미션은 JUnit4를 사용하는 테스트코드에서 예외발생했을 때 어떻게 테스트하는지입니다. 간단하게 테스트 코드에서 @test이라는 Annotation옆에 (expected = 예외명.class)
붙여주면 됩니다. 이 부분은 문법적인 내용이라 이쯤만 설명하겠습니다.
미션2. 각 도형은 중복된 Point를 입력할 수 없어야 한다.
- 중복된 Point를 입력하는 경우 DuplicatePointException을 throw 한다.
- DuplicatePointException은 RuntimeException으로 구현한다.
- 중복 Point에 대한 단위테스트를 추가한다.
위 미션을 풀어말하면 사용자가 직접 DuplicatePointException
을 만들어야 하며 RunimeException
을 상속받는다는 말입니다. 이렇게 만들고 필요에 따라 Override할 메서드를 정의하면 됩니다. 이렇게 사용자가 직접 정의한 예외 클래스를 throw 하면 실제 예외가 발생했을 때 다음과 같이 나타납니다(물론 메시지는 throw할 때 같이 적어서 보냈습니다)
이와 같은 예외를 테스트하려면 미션1에서 한 방법과 같이 @test 어노테이션 옆에 (expected = DuplicatePointException.class)
같이 적어주면 됩니다.
미션3. Point의 갯수가 1개 이하 또는 5개 이상일 경우 일치하는 도형이 없어야 한다.
- 일치하는 도형이 없을 경우 현재는 IllegalArgumentException이 발생하고 있는데 IllegalArgumentException 대신 NotFoundFigureTypeException을 throw하도록 변경한다.
- NotFoundFigureTypeException은 CompiletimeException으로 구현한다.
- 일치하는 도형이 없을 경우에 대한 단위테스트를 추가한다
이제는 예외처리에 대해 간략하게 말씀드려야겠습니다. 예외처리의 시초는 Throwable
클래스라고 보면되는데요. 그 분류도는 다음과 같습니다.
여기서 Error는 메인보드가 나갔거나 서버의 디스크 등이 고장났을 때라고 합니다. 사실 이건 예외가 아니고 에러입니다. 그 구분은 프로그램 밖에서 오류가 났느냐, 안에서 오류가 났느냐로 구분한다고 하는데요. 당연히 Error는 밖에서 발생한 경우이겠죠?
이제 Exception부분을 보겠습니다. Exception은 두 가지로 분류될 수 있습니다. 하나는 checked exception 이구요. 또 다른 하나는 예상하셨겠지만 unchecked exception 또는 runtime exception입니다. 위 그림으로 보면 RuntimeException 을 상속받는 클래스들이 unchecked exception이구요. Exception을 바로 상속받는 클래스들이 checked exception입니다.
checked가 의미하는 것이 무엇일까?
checked가 의미하는 것은 'try ~ catch문으로 묶인 것을 확인하는지' 입니다. 따라서 Exception을 상속받은 예외를 발생시킬 경우 try ~ catch 처리하지 않으면 컴파일러에서 하도록 강제합니다. 반면에 RuntimeException을 상속받은 예외를 발생시킬 때는 반드시 try ~ catch가 필요하진 않습니다. 물론 Exception을 상속받은 예외를 발생시킬 때 try ~ catch를 그곳에서 처리하기 싫다면 클래스명 옆에 throws 예외처리클래스명
을 명시하여 그곳을 호출하는 곳으로 예외처리를 떠넘길 수 있습니다. 그렇게 되면 그곳에서 try ~ catch문을 쓰도록 강제하겠죠.
RuntimeException 사용할 때 클래스명 옆에 반드시 throws
쓸 필요는 없습니다(써도 됩니다). 그러나 프로그래머가 보통 메서드를 볼 때 '입력', '출력', '예외처리'를 가장 먼저 살펴보고 메서드를 이해한다는 점에서 throws
를 명시적으로 사용하여 발생될 수 있는 예외를 나타낼 수 있다고 합니다.
그럼 이어서 미션3을 계속 진행하겠습니다. CompiletimeException으로 구현하기 때문에 try ~ catch를 강제하게 됩니다. 또는 throws를 사용하여 해당 메서드를 호출한 곳으로 예외처리를 던져버릴 수 있는데요. 따라서 main문까지 throws
예외처리를 미룬 다음 그곳에서 try ~ catch를 통해 예외처리를 하였으며 main(args)
를 다시 호출하여 다시 입력 받을 수 있도록 하였습니다.
미션4. 사용자가 Point를 잘못 입력하는 경우 에러메시지를 보여주고 다시 입력하도록 한다.
- 잘못 입력하는 경우 발생할 수 있는 Exception은 다음과 같다.
- IllegalArgumentException, DuplicatePointException, NotFoundFigureTypeException
모든 것이 처리되는 main에서 요구되는 예외처리를 받으면 다음과 같습니다.
이 경우 catch
문 안의 내용이 모두 같기 때문에 다음과 같이 줄일 수 있습니다.
에외처리에 대한 세세한 내용을 아는 것도 좋으나 제일 중요한 것은 예외처리를 어떻게 활용할 것인지, 그렇게 하여 버그가 어떻게 하면 안 발생시키도록 할 것인지가 제일 중요하다고 강조하였습니다. 성공하는 케이스는 1개인 반면 실패하는 케이스는 너무나 다양하기 때문입니다. 실제 현업에서 예외처리를 하는 것이 매우 중요하고 프로그래머들도 많은 시간을 여기에 투자하고 있다고 합니다. 또 연습거리가 늘었네요. 하하..
'Language > Java' 카테고리의 다른 글
JVM(Java Virtual Machine) (0) | 2019.01.29 |
---|---|
제네릭(Generic) (0) | 2018.11.23 |
enum (2) | 2018.10.22 |
인터페이스(Interface) (0) | 2018.10.15 |
상속(Inheritance) (3) | 2018.10.11 |