Попробуй и поймай петли - PullRequest
0 голосов
/ 08 ноября 2018

Всякий раз, когда я пытаюсь запустить свой код, он печатает "Please enter number of hours" бесконечно, пока не получит stackoverflow.

public static void hoursToDaysAndHours() throws InterruptedException {
    try {
        System.out.println("Please enter number of hours");
        Calc.fNum = Calc.input.nextDouble();
    } 
    catch (Exception e) {   
        hoursToDaysAndHours()
    }
    Calc.sNum = Calc.fNum / 24;
    Calc.awnser = Calc.fNum % 24;
    System.out.print((int) Calc.fNum + " hours = " + (int) Calc.sNum + " days and " + (int) Calc.awnser + " hours");
    Thread.sleep(5000);

    Calc.main(null);
}

Calc - это другой класс, который имеет main и объявляет переменные ... и это в классе hTDAH ...

РЕДАКТИРОВАТЬ: Как упоминалось в комментариях @Deadpool, main повторяется один раз после окончания раздела ...

3
Please enter a Celious Number
f
Please enter a Celious Number
f
Please enter a Celious Number
f
Please enter a Celious Number
fd
Please enter a Celious Number
d
Please enter a Celious Number
f
Please enter a Celious Number
dddddddddd
Please enter a Celious Number
/
Please enter a Celious Number






87654
87654.0Celcius is 157809.2 in Fahrenheit
Please enter a number between 1-4 
1 = AreaOfTriangle 
 ----------------------------------
2 = HoursToDaysAndHours Calculator 
---------------------------------- 
3 = CelciusToFahrenheit Calculator 
----------------------------------
4 = BirthdayGame 
---------------------------------- 

Please enter a number between 1-4 
1 = AreaOfTriangle 
 ----------------------------------
2 = HoursToDaysAndHours Calculator 
---------------------------------- 
3 = CelciusToFahrenheit Calculator 
----------------------------------
4 = BirthdayGame 
---------------------------------- 

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Прежде всего, не ловите Exception. Делая это, вылавливает практически все возможные исключения, включая все виды вещей, которые вы не должны ловить ... потому что вы не ожидаете их, и вы не знаете, как от них избавиться.

Во-вторых, если вы поймали исключение, которого вы не ожидаете, вам нужно как-то выяснить, что это было и чем оно вызвано. Первым шагом является печать (или запись в журнал) трассировки стека.

В-третьих, если вы получили трассировку стека, вам нужно прочитать, что там написано. Или, по крайней мере, показать это кому-то, кто может прочитать то, что он говорит. (Например, нам!)

Так что же на самом деле происходит?

Ну, есть несколько возможных объяснений, и вот некоторые из них:

  1. Если input равно null, тогда

      Calc.input.nextDouble();
    

    бросит NullPointerException. Если вы поймаете это исключение и попробуете снова (как вы делаете), это зациклится.

  2. Если следующий токен во входном потоке сканера НЕ является действительным двойным, то nextDouble() сгенерирует InputMismatchException , не пройдя мимо токена . Если вы поймаете и повторите попытку, вы получите то же самое исключение ... и вы будете зацикливаться.

  3. Здесь могут быть и другие исключения, которые могут привести к тому же результату; например NoSuchElementException и IllegalStateException.

  4. Другой сценарий состоит в том, что вы можете зацикливаться из-за

      Calc.main(null);
    

    вызов в конце метода. Это, скорее всего, вызовет вашу точку входа Calc классов снова ... вызывая цикл.

Теперь трассировка стека от вашего переполнения стека должна позволить вам различать некоторые из них, и добавление e.printStacktrace() к обработчику даст больше.

Задача: попробуйте сделать это / прочитать трассировку стека, чтобы посмотреть, сможете ли вы решить эту проблему для себя !


... так что я понимаю, что я должен привести к двойному значению

Нет. Переменная input предположительно равна Scanner. Вы не можете разыграть Scanner с удвоением.

Исходя из того, что я сказал выше, я / мы не можем (пока) сказать вам, что вам нужно сделать, чтобы это исправить. Но первый шаг - распечатать трассировку стека и прочитать ее!


Но что Double.parseDouble(Calc.input.next()) не может сделать Calc.input.nextDouble().

Они используют разные правила синтаксиса:

  • Scanner анализирует числа в соответствии с синтаксисом, который зависит от текущих настроек локали; см javadoc .
  • Double.parseDouble анализирует числа согласно нечувствительному к локали синтаксису; см javadoc .

Этого может быть достаточно, чтобы строка была действительной в одном случае, а не в другом. Это зависит от строки, которую вы пытаетесь проанализировать ... и вашего языка.

0 голосов
/ 08 ноября 2018

Один из возможных источников ошибок: В строке Calc.fNum = Calc.input.nextDouble(); вы пытаетесь прочитать входные данные из стандартного входного потока и говорите, что входные данные должны быть проанализированы как двойные. Если вход не может быть проанализирован как двойной, возникает исключение.

Теперь, глядя на ваш блок catch, вы перехватываете все исключения (catch(Exception e)). Но вместо обработки исключения вы выполняете рекурсивный вызов той же функции в блоке catch.

Таким образом, если ваш ввод не является чем-то, что может быть проанализировано как двойное, то исключение продолжает происходить, и каждый раз, когда исключение перехватывается, и в блоке перехвата происходит другой рекурсивный вызов функции hoursToDaysAndHours().

} catch (Exception e) {
    hoursToDaysAndHours() // Recursive call to the same function.
}

Таким образом, вы никогда не выйдете за пределы блока catch, если ваш ввод не является тем, что можно проанализировать как double.

Каждый рекурсивный вызов функции сохраняет текущее выполнение в стек. Это продолжается до тех пор, пока вы не исчерпаете память стека и, следовательно, не получите StackOverflowException.

Обновление: простой способ решить проблему и выполнить то, что вы пытаетесь сделать:

public class HoursToDayConverter {

    public static void hoursToDaysAndHours() throws InterruptedException {
        try {
            System.out.println("Please enter number of hours");
            Calc.fNum = Double.parseDouble(Calc.input.next());
        } catch (NumberFormatException e) {
            System.out.println("Invalid input. Try again.");
            hoursToDaysAndHours();
        }
        Calc.sNum = Calc.fNum / 24;
        Calc.awnser = Calc.fNum % 24;
        System.out.print((int) Calc.fNum + " hours = " + (int) Calc.sNum + " days and " + (int) Calc.awnser + " hours\n");

        Thread.sleep(5000);
        Calc.main(null);
    }
}
...