반응형
개요
자바과제를 진행하다 Scanner 입력값에 대한 예외처리를 위해 try catch문을 사용했는데 무한 루프에 빠지게 되었다.
문제 발생 코드
public static void main(String[] args) {
startMenu();
Scanner sc = new Scanner(System.in);
while (true) {
try {
int target = sc.nextInt();
if (target == 1) {
System.out.println("회원 관리 메뉴를 선택하였습니다.");
} else if (target == 2) {
System.out.println("과목 관리 메뉴를 선택했습니다.");
} else if (target == 3) {
System.out.println("수강 관리 메뉴를 선택했습니다.");
} else if (target == 4) {
System.out.println("결제 관리 메뉴를 선택했습니다.");
} else if (target == 5){
System.out.println("프로그램 종료합니다.");
return;
} else {
System.out.println("입력값이 정확하지 않습니다.");
}
} catch (InputMismatchException e) {
System.out.println("입력값이 정확하지 않습니다.");
} finally {
startMenu();
}
}
}
문제가 발생되는 코드는 다음과 같다. 이 코드를 수행하면 정수값이 아닌 다른 문자값을 입력받으면 예외처리(catch)가 수행되며 시작메뉴 선택 메시지가 표현되게 하려고 하였다.
하지만 수행 시 "입력값이 정확하지 않습니다." 구문과 startMenu() 메서드가 무한호출되는 문제가 발생하였다.
문제의 원인 및 해결
디버깅 결과 nextInt() 값에 지속적으로 초기 입력한 문자값이 적용되는 것을 확인하였다.
해당 이슈를 찾아보니 정상처리 되면 버퍼의 헤드가 빠져나와 문제가 발생되지 않지만 예외처리하면 잘못된 입력이 여전히 입력 버퍼에 남아있게되어 문제가 발생한다고 한다.
이 문제를 해결하기 위해 `catch` 블록에서 예외가 발생 시, 입력 버퍼에서 잘못된 입력을 소비(consume)시켜줘야 한다. 따라서 다음 코드와 같이 `sc.nextLine()`을 추가하여 잘못된 입력을 소비시켜줘야 한다.
catch (InputMismatchException e) {
System.out.println("입력값이 정확하지 않습니다.");
sc.nextLine(); // 잘못된 입력 소비
}
Scanner 클래스의 nextLine() 메소드는 엔터 치기 전까지 쓴 문자열을 모두 리턴하며 이로써 사용 중인 버퍼를 비울 수 있게 된다.
반응형