Логически правильная спецификация метода StringUtils.isNumeric()?

Apache StringUtils.isNumeric() спецификация метода говорит:
Проверяет, содержит ли строка только цифры в Unicode. Десятичная точка не является символом юникода и возвращает false. Null вернет false. Пустой String ("") вернет true.

Является ли это логически правильным? Почему они видят пустую строку как числовую?

Ответ 1

Не только я спросил этот вопрос:) Люди открыли этот дефект в Apache Jira: https://issues.apache.org/jira/browse/LANG-428

Они закрываются, не исправляя их только для обеспечения обратной совместимости (чтобы следовать спецификации метода).

Но все согласились с тем, что текущее поведение метода неверно.

Ответ 2

Поведение изменилось в версии 3.0. Из Что нового в Commons Lang 3.0?:

StringUtils.isAlpha, isNumeric и isAlphanumeric, теперь все возвращают false при передаче пустой строки. Раньше они вернулись.

Сохранение старого ответа ниже, для справки и для пользователей до 3.0.


Является ли это логически правильным?

Мы имеем

  • поведение метода
  • документация метода (который часто рассматривается как спецификация или контракт)
  • имя метода

В этом случае 1 и 2 согласуются друг с другом; Все символы пустой строки являются символами юникода. (Или, что то же самое, никакие символы в пустой строке не являются символами unicode.) Это то, что логики называют vacuously true и несколько противостоят интуитивному. Это похоже на то, что все слоны в моей квартире зеленые. Это правда, поскольку в моей квартире нет слонов.

Пункт 3, однако (имя метода), естественно интерпретируется как метод, который возвращает true, если данная строка представляет число.

Итак, будь то ошибка в документации и реализации, или это ошибка в именах. Там нет правильного или неправильного ответа на этот вопрос.

Ошибка была отправлена ​​здесь. Составители утверждают, что они предполагали поведение.

Почему они видят пустую строку как числовую?

В то время как имя метода может заставить вас полагать, что метод должен возвращать true только для строк, которые представляют число, спецификация фактически говорит, что она должна возвращать значение true, если строка содержит только цифры в unicode.

Вы говорите,

Я запутался, потому что спецификация говорит: "Проверяет, содержит ли строка только цифры в Unicode". Я не вижу, что "" содержит цифры....

Обратите внимание, что пустая строка не содержит ничего, кроме цифр юникода. Поэтому метод возвращает true.

Ответ 3

java.lang.Integer.parseInt("") завершится с ошибкой.

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

Если имя метода containsOnlyNumeric(), естественно вернуть true для "в соответствии с нашими учебниками по математике. Однако имя метода isNumeric(), обращение с" " не является естественным. Кроме того, нет очевидной причины, по которой null должен возвращать false. Я бы выбрал исключение для null.

Но это то, что есть, хорошо документировано и что еще вы можете попросить?

Ответ 4

сначала проверьте условие, что строка пуста() или нет.

if(StringUtils.isNotEmpty(str) && StringUtils.isNumeric(str)) {

}

тогда ваша проблема будет решена.

но еще одна проблема заключается в том, что вы передаете отрицательные значения, например

str = "-1";

StringUtils.isNumeric(str) он будет ложным.

Вам нужно позаботиться об этом условии.

Ответ 5

Существует другое решение. NumberUtils.isNumber Это проверяет, является ли это числом Long, Double, Integer.

Надеемся на эту помощь