Почему трассировка стека содержит повторный вызов метода parseInt()?

#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. По-видимому, трассировка стека показывает только имя метода, его имя файла и номер строки, но не сигнатуру метода.