#java #string #exception #integer #parseint
#java #строка #исключение #целое число #parseint
Вопрос:
Я скомпилировал следующий код с помощью JDK 11.0:
import java.util.Scanner;
public class inputWithScanner {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter your name and roll number");
String name = input.next();
Integer rollNumber = Integer.parseInt(input.next());
input.close();
if (name.isEmpty())
System.out.println("oops! You didnt enter your name");
if (rollNumber < 0)
System.out.println("Enter a valid roll number");
System.out.println("Hello " name " Roll Number " rollNumber);
и протестировал программу со следующим вводом (смешанный ввод для переменной rollNumber является преднамеренным):
Enter your name and roll number
Manraj 2018CSE1023
компилятор создает исключение: NumberFormatException с трассировкой стека следующим образом:
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at inputWithScanner.main(inputWithScanner.java:7)
Вопрос в том:
Почему существует повторный вызов метода parseInt()?
Я попробовал тот же код с методом valueOf() и выполнил программу с тем же вводом. Компилятор генерирует то же исключение, и трассировка стека выглядит следующим образом:
Exception in thread "main" java.lang.NumberFormatException: For input string: "2018CSE1023"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.valueOf(Integer.java:983)
at inputWithScanner.main(inputWithScanner.java:7)
Это показывает, что метод valueOf() вызывает метод parseInt(). Но почему parseInt() вызывает сам себя?
Комментарии:
1. Привет, это происходит потому, что
2018CSE1023
недопустимое число и чтобы это исправить. Вам нужно будет сохранить эту переменную какString
2. Как я уже упоминал, вопрос связан с трассировкой стека, а не с ошибкой в этой программе. Входные данные намеренно задаются отличными от ожидаемых.
3. Когда метод перегружен, обычно одну перегрузку реализуют как вызов другой. Это отображается в stacktrace в виде двух (или более) последовательных кадров с одинаковым именем метода. Но это не тот же метод.
Ответ №1:
parseInt
определяется как
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,10); // this is line 770 currently
}
Затем в строке 652 (внутри этого внутреннего вызова parseInt
) он выдает исключение. В этот момент как с двумя аргументами parseInt
, так и с одним аргументом один находятся в трассировке стека.
Короче говоря, это два разных метода, один с одним аргументом, который вызывает один с двумя.
valueOf
определяется как
public static Integer valueOf(String s, int radix) throws NumberFormatException {
return Integer.valueOf(parseInt(s,radix));
}
Который вызывает версию с двумя аргументами напрямую.
Комментарии:
1. Полезно знать. Спасибо, Федерико.
2. По-видимому, трассировка стека показывает только имя метода, его имя файла и номер строки, но не сигнатуру метода.