Как правильно обрабатывать исключение NumberFormatException, когда оно ожидается?

StackOverflow https://stackoverflow.com/questions/4410107

Вопрос

Я столкнулся с такой ситуацией, когда мне нужно проанализировать String в int и я не знаю, что делать с NumberFormatException.Компилятор не жалуется, когда я его не улавливаю, но я просто хочу убедиться, что я правильно справляюсь с этой ситуацией.

private int getCurrentPieceAsInt() {
    int i = 0;
    try {
        i = Integer.parseInt(this.getCurrentPiece());
    } catch (NumberFormatException e) {
        i = 0;
    }
    return i;
}

Я хочу просто упростить свой код вот так.У компилятора нет проблем с этим, но поток умирает на NumberFormatException.

private int getCurrentPieceAsInt() {
    int i = 0;
    i = Integer.parseInt(this.getCurrentPiece());
    return i;
}

Google CodePro хочет, чтобы я каким-то образом зарегистрировал исключение, и я согласен, что это лучшая практика.

private int getCurrentPieceAsInt() {
    int i = 0;
    try {
        i = Integer.parseInt(this.getCurrentPiece());
    } catch (NumberFormatException e) {
        i = 0;
        e.printStackTrace();
    }
    return i;
}

Я хочу, чтобы этот метод вернулся 0 когда текущая часть не является числом или не может быть проанализирована.Когда я не улавливаю NumberFormatException явно, не присваивает ли он переменной i?Или есть какое-то значение по умолчанию, которое Integer.parseInt() возвращается?

Общий стиль гласит, что если я поймаю исключение, я должен где-то его зарегистрировать.Я не хочу это регистрировать.Это нормальное явление, когда иногда выбрасывается это исключение, что меня тоже не устраивает.Однако я не могу найти функцию, которая сообщит мне, если Integer.parseInt() выдаст исключение.Поэтому мой единственный вариант действий — просто вызвать его и перехватить исключение.

А Javadoc для parseInt не особо помогает.

Вот конкретные вопросы, которые я хотел бы знать:

  • Есть ли метод, который я могу вызвать, который скажет мне, если Integer.parseInt() бросит NumberFormatException прежде чем позвонить?Тогда у меня не было бы проблем зарегистрировать это, поскольку этого никогда не должно произойти.
  • Если я просто не перехватываю исключение, не будет ли присвоено значение valiable?Затем я просто инициализирую его нужным мне значением, если оно не является числом, и не перехватываю исключение.
  • Есть ли способ как-то явно обозначить исключение, чтобы оно меня не волновало?Я думаю, это будет что-то похожее на AWTEvent.consume().Если да, то я сделаю это, чтобы Google CodePro не считал это «незарегистрированным».
Это было полезно?

Решение

  • Есть ли метод, который я могу вызвать, который сообщит мне, вызовет ли Integer.parseInt() исключение NumberFormatException перед его вызовом?Тогда у меня не было бы проблем зарегистрировать это, поскольку этого никогда не должно произойти.

К сожалению нет.По крайней мере, не в ядре Java API.Однако написать его несложно — просто измените приведенный ниже код.

  • Если я просто не перехватываю исключение, не будет ли присвоено значение valiable?Затем я просто инициализирую его нужным мне значением, если оно не является числом, и не перехватываю исключение.

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

  • Есть ли способ как-то явно обозначить исключение, чтобы оно меня не волновало?Я думаю, это будет что-то похожее на AWTEvent.consume().Если да, то я сделаю это, чтобы Google CodePro не считал это «незарегистрированным».

Возможно, существует способ указать CodePro игнорировать это конкретное предупреждение.Конечно, с помощью таких инструментов, как FindBugs и Checkstyle, вы можете отключить предупреждения в определенных местах.(РЕДАКТИРОВАТЬ:@Энди указал, как это сделать.)

Я подозреваю, что вам нужно что-то вроде языкового пакета Commons, упомянутого @daveb.Написать такую ​​функцию довольно легко:

int parseWithDefault(String s, int def) {
    try {
        return Integer.parseInt(s);
    }
    catch (NumberFormatException e) {
        // It's OK to ignore "e" here because returning a default value is the documented behaviour on invalid input.
        return def;
    }
}

Другие советы

Есть NUMBUTILS.Toint (строка, int) в Commons Lang Что будет делать именно то, что вы хотите.

NumberUtils.toInt("123", 42) ==> 123
NumberUtils.toInt("abc", 42) ==> 42
* Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".

Да, вы можете локально отключить правило аудита CodePro для одной строки кода:

http://code.google.com/javadevtools/codePro/doc/features/audit/locally_disabling_audit_rules.html.

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

Создайте свой собственный метод удобства на данный момент и будущее Использование:

public static int parseInt(final /*@Nullable*/ String s, final int valueIfInvalid) {
    try {
        if (s == null) {
            return valueIfInvalid;
        } else {
            return Integer.parseInt(s);
        }
    } catch (final NumberFormatException ex) {
        return valueIfInvalid;
    }
}

Существует ли метод, который я могу позвонить, это скажет мне, если INTEGER.PARSEINT () бросит invermatexception, прежде чем вызвать его? Тогда у меня не было бы проблем, войдя в систему, так как никогда не должно произойти.

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

Если я просто не поймаю исключение, валютный не будет назначен? Тогда я просто инициализирую его к значению, который я хочу, когда это не число, а не поймать исключение.

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

Есть ли способ отметить исключение как-то явно, что мне все равно? Я думаю, что это было бы чем-то похожем на awtevent.consume (). Если это так, то я сделаю это так, чтобы Google CodePro не видит этого как «unologged».

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

Я бы не зарегистрировал его, если это действительно нормальное состояние, которое вы обрабатываете. Я не снимаю с помощью Google CodePro, но я надеюсь, что есть способ подавить предупреждение, например, каким-то образом @suppresswarnings («xxx») аннотация / ключевое слово.


Редактировать: Я хотел указать эти комментарии в комментариях ниже

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

.

... исключение (ситуация) обрабатывается Возвращая указанное значение CatchLifinValid. То "плохой тон" Вы имеете в виду Плохая практика слепо и недомасшительно написания пустых лоблов И никогда не возвращаюсь, чтобы по-настоящему рассмотреть и обратиться к делу. Если то Ситуация исключения считается и делает правильную вещь для ситуации (Даже если правильная вещь - ничего не делать), тогда Вы «обрабатывали» исключение.

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

Нет метода API Java, который вернется 0, когда строка не является действительным INT.

Когда строка не является int, исключение будет брошено, чтобы ваша переменная INT не будет установлена, если вы не поймаете исключение, как вы делаете.

Если это не ясно, как вы должны обрабатывать его с добытеля, вы не должны ловить его и позволить абоненту с ней вместо этого. Если вы знаете, как это должно быть обработано, вы должны просто сделать это. Регистрация не требуется или очень полезно в этом случае.

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

Ваш первый код кода правильный. i Не будет неявно преобразован в 0, когда происходит исключение, и вы должны поймать это исключение. Параметр i до 0 внутри catch верно; Хотя вы можете просто заменить i = 0; с участием return 0;. Отказ Вы не можете избежать обработки исключений в этом случае.

Чтобы уточнить, вы можете использовать это:

private int getCurrentPieceAsInt() {
    int i = 0;
    try {
        i = Integer.parseInt(this.getCurrentPiece());
    } catch (NumberFormatException e) {
        // log that an exception occured if it's needed
        return 0;
    }
    return i;
}

Как упомянули другие, нет встроенного метода Core Java API, который вы можете позвонить, чтобы проверить целое число, но вы можете использовать Character класс для проверки вашего ввода без используя обработку исключений. Например:

package com.example.parseint;

public class ValidateIntExample {
    public static boolean isInteger(String s) {
        if (s == null) {
            return false;
        }

        s = s.trim();

        if (s.length() == 0) {
            return false;
        }

        int start = 0;
        if (s.charAt(0) == '-') { // handle negative numbers
            if (s.length() == 1) {
                return false;
            }
            else {
                start = 1;
            }
        }

        for (int i = start; i < s.length(); i++) {
            if (! Character.isDigit(s.charAt(i))) {
                return false;
            }
        }

        return true;
    }
}

Фактически, parseInt сам использует Character.isDigit Внутренне, который вы можете проверить в исходном коде JRE. (Извините, я бы включил parseInt Метод здесь, но я не уверен, что мне разрешено в соответствии с условиями лицензии.) Если вы используете Eclipse, и у вас есть исходный код JRE, прикрепленный к вашему проекту, вы можете щелкнуть правой кнопкой мыши по методу Integer.parseInt В вашем коде и нажмите Открыть декларацию.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top