try - catch with 재귀호출 + return value "변수의 scope"

solar·2020년 2월 8일
0

JAVA

목록 보기
5/6

사용자로 부터 입력을 받는 두 메서드에 중복된 코드를 줄이는 것이 목표

// 원본 - 중복된 코드가 존재
public void inputInfo() {
  inputMonsterInfo();
  inputAttemptInfo();
}

public void inputMonsterInfo() {
  try {
    String promptMonster = "몬스터는 모두 몇 마리인가요?";

    System.out.println(promptMonster);
    monsterCount = Integer.parseInt(scanner.nextLine());
  } catch (NumberFormatException e) {
    System.out.println("숫자 값만 입력하실 수 있습니다. 다시 입력해주세요.");
    inputMonsterInfo();
  }
}

public void inputAttemptInfo() {
  try {
    String promptMonster = "시도할 회수는 몇 회 인가요?";

    System.out.println(promptMonster);
    attemptCount = Integer.parseInt(scanner.nextLine());
  } catch (NumberFormatException e) {
    System.out.println("숫자 값만 입력하실 수 있습니다. 다시 입력해주세요.");
    inputAttemptInfo();
  }
}

다음과 같이 사용자 입력을 받는 부분과 변수에 값을 저장하는 부분을 분리하였다.

// 잘못짠 코드
private void inputMonsterInfo() {
  String promptMonster = "몬스터는 모두 몇 마리인가요?";
  monsterCount = inputProperType(promptMonster);
}

private void inputAttemptInfo() {
  String promptMonster = "시도할 회수는 몇 회 인가요?";
  attemptCount = inputProperType(promptMonster);
}

private Integer inputProperType(String promptMesssage) {
  int inputValue;
  try {
    System.out.println(promptMesssage);
    inputValue = Integer.parseInt(scanner.nextLine());
  } catch (NumberFormatException e) {
    System.out.println("숫자 값만 입력하실 수 있습니다. 다시 입력해주세요.");
    inputProperType(promptMesssage); // 재귀함수를 호출한 곳으로 돌아오고 아래 코드 마저 실행
    return -1; //무조건 -1을 리턴하게 된다.
  }
  return inputValue;
}

inputProperType() 메서드에서 사용자 입력값의 타입이 적절한지 확인 후, 적절한 입력값인 경우 입력값을 반환하고, 아닌 경우 발생한 에러를 내부의 catch에서 받아 문구를 출력 후, 재귀 호출을 하였다.

잘못된 입력을 받았을 경우의 return은 어떻게 할까

잘못된 입력값일 경우 catch에서 inputProperType(promptMessage); 호출을 하는 것까지만 짜면 에러발생시 return 값이 없으므로 에러가 났다.

-1 을 return 해볼까? -> Nope....

아래처럼 코드를 짜면 재귀호출된 inputProperType(promptMessage); 가 수행 종료 후, 호출된 곳으로 돌아와서 아래의 return -1 코드를 실행하게 되므로 결국에는 재귀호출이 수행되면 무조건 -1값만 return하게 된다.

해결책

return inputProperType(promptMesssage); 그냥 이렇게 해주면된다. 재귀호출을 반복하다가 정상적으로 입력받게되면 inputProperType(promptMesssage);inputValue 값을 가지고 오게되고 이 값을 그대로 return 해주면 된다.!!!!

굳이 값을 설정하지 않았어도 되는건데!! 헤맸다 (여기서 끝난게 아님)

public void inputInfo() {
  inputMonsterInfo();
  inputAttemptInfo();
}

private void inputMonsterInfo() {
  String promptMonster = "몬스터는 모두 몇 마리인가요?";
  monsterCount = inputProperType(promptMonster);
}

private void inputAttemptInfo() {
  String promptMonster = "시도할 회수는 몇 회 인가요?";
  attemptCount = inputProperType(promptMonster);
}

private Integer inputProperType(String promptMesssage) {
  int inputValue; //지역변수
  try {
    System.out.println(promptMesssage);
    inputValue = Integer.parseInt(scanner.nextLine());
    return inputValue;
  } catch (NumberFormatException e) {
    System.out.println("숫자 값만 입력하실 수 있습니다. 다시 입력해주세요.");
    return inputProperType(promptMesssage);
  }
}

inputValue를 메서드의 지역변수로 선언하지 않고, try {} 안의 코드블력 변수로 선언하면 더 좋을 듯하다.

코드블럭의 생명주기를 따르는 것이 더 적합한 듯.

public void inputInfo() {
  inputMonsterInfo();
  inputAttemptInfo();
}

private void inputMonsterInfo() {
  String promptMonster = "몬스터는 모두 몇 마리인가요?";
  monsterCount = inputProperType(promptMonster);
}

private void inputAttemptInfo() {
  String promptMonster = "시도할 회수는 몇 회 인가요?";
  attemptCount = inputProperType(promptMonster);
}

private Integer inputProperType(String promptMesssage) {
  try {
    System.out.println(promptMesssage);
    int inputValue = Integer.parseInt(scanner.nextLine()); //코드블럭 변수
    return inputValue;
  } catch (NumberFormatException e) {
    System.out.println("숫자 값만 입력하실 수 있습니다. 다시 입력해주세요.");
    return inputProperType(promptMesssage);
  }
}

참고
https://bvc12.tistory.com/194

profile
nunnu

0개의 댓글