Как правильно структурировать этот набор блоков try catch в отношении инициализации переменных?

#java #error-handling

Вопрос:

Я практикуюсь в java, пробуя свои силы в простом вызове с калькулятором из онлайн-курса. Цель состоит в том, чтобы принимать числовые входные данные плюс требуемую операцию ( , -, %, *), при одновременной обработке нечисловых входных данных и незарегистрированных операторов. Ниже приведена моя попытка:

     public static void main(String[] args) {

        double d1;
        double d2;

        Scanner sc = new Scanner(System.in);
        try {
            d1 = getInput(sc);
            d2 = getInput(sc);
        } catch (InputMismatchException e) {
            System.out.println("Non numeric value entered.");
            System.exit(0);
        }

        try {
            System.out.println(calculate(sc, d1, d2));
        } catch(OperationNotSupportedException e){
            System.out.println(e.getMessage());
        }
    }

 private static double calculate(Scanner scanner, double d1, double d2) throws OperationNotSupportedException {
        System.out.print("Enter the desired operation: ");
        String op = scanner.next();
        System.out.println(op);

        switch (op) {
            case "-":
                return d1 - d2;
            case " ":
                return d1   d2;
            case "*":
                return d1 * d2;
            case "/":
                return d1 / d2;
            default:
                throw new OperationNotSupportedException("The operation not one of (  - % *)");
        }
    }

    private static double getInput(Scanner sc) {
        System.out.printf("Enter a numeric value: ");
        return sc.nextDouble();
    }

 

Таким образом, проблема в том, что компилятор видит проблему во втором try-catch блоке. А именно d1 и d2 , возможно, не были инициализированы. Я понимаю, почему это было бы верно в том случае, если в первом случае возникает ошибка try-catch . Я подумал, что это System.exit() может удовлетворить компилятора, но это не так.

Как я мог бы реструктурировать свой код для достижения желаемых результатов?

Комментарии:

1. В данном конкретном случае я бы переместил то, что во втором try , в первое try и поймал там оба исключения. Как только один из них пойман, нет сомнений, что один был брошен, getInput а другой-из calculate

2. exit () — это просто вызов метода. Компилятор не знает, что определенный метод не вернется. Что касается меня, я бы просто инициализировал d1 и d2 (подойдет 0). Но я согласен с @FedericoklezCulloca; как написано, похоже, нет необходимости в двух блоках попыток.

3. @FedericoklezCulloca Хорошо, это имеет смысл!

4. @что-то справедливое. Наверное, я думал, что это может быть непрозрачно для компилятора.

Ответ №1:

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

просто инициализируйте как:

 double d1 = 0d;
double d2 = 0d;
 

Комментарии:

1. Спасибо. Я решил объединить два блока try-catch, как было предложено в комментариях. Тем не менее, я приму ваш ответ, так как это явно решит мою проблему.

2. @rocksNwaves Да, вы можете объединить эти блоки try и использовать несколько блоков catch для обработки конкретного исключения, поскольку ваши операторы catch, похоже, различаются для каждого исключения. В противном случае вы могли бы использовать один улов, такой как : catch(InputMismatchException | OperationNotSupportedException e)