회고록 블로그
[공부 필기] Java 기본 공부하기 (22) 본문
공부 중인 강의 : 윤성우 선생님, 윤성우의 열혈 Java 프로그래밍 강의.
링크 : https://cafe.naver.com/cstudyjava
1. 예외 클래스 직접 정의하기
- 필요에 따라 프로그래머가 직접 예외 클래스를 정의할 때도 있음
- 프로그램을 구현하다보면 "논리적 예외"가 발생할 수도 있음
→ 코드가 잘못된 것은 아님
→ e.g. 사용자에게 주민등록번호를 입력받을 때 뒷자리 첫번째는 1, 2, 3, 4 중의 하나이어야하는데 9가 입력됨 등
- 예외 클래스를 직접 정의하는 방법
→ 1번. Exception 클래스를 상속함
class CheckResidentNumberException extends Exception {
....
}
→ 2번. 메시지를 등록하고 싶다면 super 키워드를 이용해서 상위클래스의 생성자를 호출함
* super의 인자로 문자열을 전달하면 Throwable 생성자에 의해 detailMessage에 값이 대입됨 ([그림1] 참고)
class CheckResidentNumberException extends Exception {
public CheckResidentNumberException() {
super("유효하지 않은 주민등록번호");
}
}
2. 직접 정의한 예외 클래스를 "예외를 처리하는 과정"에 적용하기
- 1을 통해 예외 클래스를 직접 정의하는 것까지는 완료됨
- 이제 "예외를 처리하는 과정"에 우리가 정의한 예외 클래스를 적용해야함
→ 간단하게 정리하자면,
→ 1) JVM이 프로그램의 코드를 읽으면서 '프로그래머가 정의한 예외 상황'이 있는지 찾을 수 있도록 해야하고
→ 2) 만약 해당 예외가 존재하면 실행을 멈추고
→ 3) '프로그래머가 정의한 예외 인스턴스'를 생성토록 해야하고
→ 4) 그 다음 try ~ catch문이 있는지 확인하는 과정이 있어야함
- 적용한 예시
→ 코드 설명
/* CheckResidentNumberException 클래스
* 위에서 언급한 '예외처리 과정'에서 3)에 해당하는 인스턴스가 될 클래스이다.
* 사용자로부터 유효하지 않은 주민등록번호가 입력되면 생성되도록 구성할 예정.
*/
class CheckResidentNumberException extends Exception {
public CheckResidentNumberException() {
super("유효하지 않은 주민등록번호");
}
}
/* ReadResidentNumber 클래스
* 우선 사용자로부터 값(주민등록번호)을 입력 받아 변수에 저장하며
* 주민등록번호 뒷자리의 왼쪽 첫번째 숫자(변수 firstDigit)를 체크해서 1~4 이외의 숫자가 있으면 예외를 발생시킨다.
* 그 예외는 ReadResidentNumber를 호출한 메인 메소드에서 try~catch문으로 처리할 예정.
*/
import java.util.Scanner;
public class ReadResidentNumber {
int frontNumber;
int backNumber;
public ReadResidentNumber() {
Scanner sc = new Scanner(System.in);
frontNumber = sc.nextInt(); // 주민등록번호 앞자리
backNumber = sc.nextInt(); // 주민등록번호 뒷자리
}
public int checkResidentNumberFirstDigit() throws CheckResidentNumberException {
Scanner sc = new Scanner(System.in);
int firstDigit = backNumber / 1000000; // 뒷자리 첫번째 숫자만 추출
switch(firstDigit) {
case 1:
case 2:
case 3:
case 4:
break;
default:
throw new CheckResidentNumberException(); // 예외 발생
}
return firstDigit;
}
}
/* Main 클래스 (메인메소드가 있는 메소드이다)
* ReadResidentNumber에서 발생한 예외를 try ~ catch문으로 처리하는 역할을 할 예정.
*/
public class Main {
public static void main(String[] args) {
ReadResidentNumber person = new ReadResidentNumber();
try {
int digit = person.checkResidentNumberFirstDigit();
System.out.println("주민등록번호 뒷자리 첫번째 숫자는 "+digit+" 입니다.");
}
catch(CheckResidentNumberException e) {
e.printStackTrace();
}
}
}
- 방법(정리)
→ ReadResidentNumber 클래스의 아래 코드는 예외를 발생시키는 역할을 함 (= throw 키워드)
* 예외를 발생시킨 덕분에 JVM은 실행을 잠시 멈추고 예외를 처리하기 위한 매커니즘을 구동하기 시작함
→ 그리고 예외 클래스(CheckResidentNumberException)를 생성(= new 키워드) 해주었음
* 보통 JVM이 자동으로 예외 인스턴스를 생성해주지만, 여기에서는 프로그래머가 직접 인스턴스를 생성해줘야함
* 그렇기 때문에 new 키워드를 이용해서 인스턴스를 생성해줌
...
throw new CheckResidentNumberException(); // 예외 발생
...
→ 이후는 다른 Exception을 상속하는 클래스들과 동일함
* 예외를 처리하기 위해 1) try ~ catch문을 찾거나 2) throws로 예외 처리의 책임을 던져야함
* 예시의 코드에서는 throws 키워드로 예외 처리의 책임을 '호출한 곳'으로 던졌음 (아래 코드 참고)
...
public int checkResidentNumberFirstDigit() throws CheckResidentNumberException {
...
→ 해당 메소드를 호출한 곳(=예시에서는 메인메소드)으로 가보니 try ~ catch문이 있고,
catch문의 인자로 CheckResidentNumberException 인스턴스를 전달할 수 있어서 예외 처리를 함 (아래 코드 참고)
...
try {
int digit = person.checkResidentNumberFirstDigit();
System.out.println("주민등록번호 뒷자리 첫번째 숫자는 "+digit+" 입니다.");
}
catch(CheckResidentNumberException e) {
e.printStackTrace();
...
→ 예외를 다 처리한 후에는 try문 밖에 있는 코드부터 다시 하나씩 실행함
3. 다중 catch문 주의하기
- 아래와 같이 구성한 경우
→ 상속관계가 아래와 같이 되어있는 Exception 클래스들
→ 이때, CException 예외가 발생하면 3개의 catch문 중에서 어느 catch문이 실행될까
* 정답은 catch(AException e)문이 실행됨
→ 그 이유는 상속의 특성 때문임
* catch(AException e)의 참조변수 e는 AException e = new CException(); 과 동일한 코드임
* CException e = new AException();은 불가능하지만, AException e = new CException();은 가능함
→ 위와 같이 구성하면 두번째와 세번째 catch문은 한번도 실행되지가 않음
→ 따라서 상속의 특성에 의해서 순서를 변경해야함
'2. 프로그래밍 언어 공부 > Java' 카테고리의 다른 글
[공부 필기] Java 기본 공부하기 (24) (0) | 2021.12.01 |
---|---|
[공부 필기] Java 기본 공부하기 (23) (0) | 2021.11.30 |
[Java 공부] Scanner 클래스의 useDelimiter 메소드를 이용해서 구분자를 쉼표로 변경해보기 (1) | 2021.11.30 |
[공부 필기] Java 기본 공부하기 (21) (0) | 2021.11.24 |
[공부 필기] Java 기본 공부하기 (20) (0) | 2021.11.23 |