#java
#java
Вопрос:
Я пишу программу, которая вычисляет чаевые и общую сумму из счета и ставки чаевых.
public void takeUserInput() {
Scanner sc = new Scanner(System.in);
double billAmount;
int tipRate;
try {
System.out.print("What is the bill? ");
billAmount = sc.nextDouble();
System.out.print("What is the tip percentage? ");
tipRate = sc.nextInt();
tc.calculate(billAmount, tipRate);
} catch (InputMismatchException e1) {
String errorMessage = "Please enter a valid number for the ";
// errorMessage = billAmount or
// errorMessage = tipRate ?
}
Я ищу способ узнать, какая переменная вызывает исключение InputMismatchException, чтобы я мог добавить имя переменной в переменную ErrorMessage и распечатать на экране.
Комментарии:
1. @Andreas Я знаю этот метод, но мне нужно имя переменной.
2. Ни один из них не выдал бы это исключение, если бы вы просто проверили правильность перед вызовом
nextXxx()
, используяhasNextXxx()
.3. @Andreas Я не использую операторы цикла.
4. Где в этом предыдущем комментарии я говорил что-нибудь о циклах?
5. @Andreas Извините, я знал, что этот метод используется только в цикле.
Ответ №1:
Есть несколько простых способов добраться туда:
- Вызовите hasNextXXX() перед вызовом nextXxx() .
- Если вы используете один блок try / catch для каждого ввода, в вашем блоке catch очень ясно, какая переменная вызвала проблему (затем вы можете вызвать общий метод с конкретным сообщением об ошибке, чтобы избежать дублирования кода)
- Вы могли бы использовать ссылочные типы для своих переменных; если вы используете Double / Integer вместо double / int … вы можете проверить, какая из двух переменных по-прежнему равна нулю
- Вы вводите небольшую логическую переменную, например
billAmountIsValid
. Изначально эта переменная имеет значение false, вы превращаете ее в true после вызова nextDouble() . Затем вы можете легко проверить в своем блоке try, получили ли вы действительный счет.
После еще некоторых размышлений: вы действительно хотите комбинацию 1 2: вы видите; когда пользователи вводят правильное количество счетов; почему вы хотите забыть об этом значении, когда второе значение дает неверное второе значение? Нет — вы должны выполнять цикл для каждой переменной, пока не получите действительный ввод. И только тогда вы начинаете запрашивать следующее значение!
Комментарии:
1. 4. Вызовите
hasNextXxx()
beforenextXxx()
.2. Спасибо. Хорошая идея; добавил это в список в качестве первой записи!
3. См. Следующее, почему отказ от использования исключений (вариант 1) может быть лучшим решением: считаются ли исключения как поток управления серьезным антипаттером? Если да, то почему?
4. @Andreas Спасибо, я не знал, что этот способ будет антипаттерновым.
5. @GhostCat я решил с помощью ответа Уэстона. Извините. На данный момент его путь для меня прост.
Ответ №2:
Переменная не генерирует исключение, выполняется оценка правой части присваивания переменной, и поэтому в исключении нет информации, указывающей, какой переменной она собиралась присвоить это, если бы это удалось.
Вместо этого вы могли бы рассмотреть новый метод, который включает в себя сообщения с запросами и повторные попытки:
billAmount = doubleFromUser(sc, "What is the bill? ", "bill");
Где doubleFromUser
:
static double doubleFromUser(Scanner sc, String prompt, String description){
while(true) { //until there is a successful input
try {
System.out.print(prompt); //move to before the loop if you do not want this repeated
return sc.nextDouble();
} catch (InputMismatchException e1) {
System.out.println("Please enter a valid number for the " description);
}
}
}
Вам понадобится другая для int и double , но если у вас будет больше подсказок, вы сэкономите в долгосрочной перспективе.