Является ли метод метода StringUtils.isNumeric () логически правильным? - PullRequest
10 голосов
/ 20 октября 2010

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

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

Ответы [ 5 ]

13 голосов
/ 20 октября 2010

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

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

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


Это логически правильно?

У нас есть

  1. поведение метода
  2. документация о методе (которая часто рассматривается как спецификация или контракт)
  3. название метода

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

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

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

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

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

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

Вы говорите,

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

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

5 голосов
/ 20 октября 2010

java.lang.Integer.parseInt("") потерпит неудачу.

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

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

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

4 голосов
/ 17 апреля 2014

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

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

}

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

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

str = "-1";

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

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

4 голосов
/ 20 октября 2010

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

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

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

0 голосов
/ 28 июля 2015

Есть другое решение. NumberUtils.isNumber Это проверяет, является ли это число длинным, двойным, целым.

Надеюсь, эта помощь

...