Question

Apache's StringUtils.isNumeric() method specification says:
Checks if the String contains only unicode digits. A decimal point is not a unicode digit and returns false. Null will return false. An empty String ("") will return true.

Is this logically right? Why do they see empty string as numeric?

Was it helpful?

Solution 3

There was not only me who asked this question :) People were opening this defect in Apache's Jira: https://issues.apache.org/jira/browse/LANG-428

They closed without fixing it only to keep backwards compatibility (to follow method specification).

But everybody agreed that current behavior of method is wrong.

OTHER TIPS

The behavior changed in 3.0. From What's new in Commons Lang 3.0?:

StringUtils.isAlpha, isNumeric and isAlphanumeric now all return false when passed an empty String. Previously they returned true.

Keeping old answer below, for reference and for pre 3.0 users.


Is this logically right?

We have

  1. the behavior of the method
  2. the documentation of the method (which is often viewed as the specification or contract)
  3. the name of the method

In this case 1 and 2 agree with each other; All characters in the empty string are unicode digits. (Or equivalently, no characters in the empty string are not unicode digits.) This what logicians call vacuously true and somewhat counter intuitive. It's like saying that all elephants in my apartment are green. It's true, since there are no elephants in my apartment.

Item 3 however (the name of the method) is naturally interpreted as a method that returns true if the given string represents a number.

So, either it's a documentation and implementation bug, or it's a naming bug. There's no right or wrong answer to that.

A bug was filed here. The maintainers take the stand point that it's intended behavior.

Why do they see empty string as numeric?

While the name of the method may lead you to believe the method should return true only for strings that represents a number, the spec actually says it should return true for if the string contains only unicode digits.

You say,

I'm confused because specification says: "Checks if the String contains only unicode digits." I don't see that "" contains digits....

Note that the empty string does not contain anything else than unicode digits. Therefore the method returns true.

java.lang.Integer.parseInt("") will fail.

It's not a matter of logic. It's not a matter of common sense either - there wasn't any number that's represented by no symbol. There's no strong argument why an empty string should represent 0.

If the method name is containsOnlyNumeric(), it is natural to return true for "" according to our math textbooks. However, the method name is isNumeric(), the treatment of "" isn't natural. Also, there's no apparent reason why null should return false. I would throw exception for null.

But it is what it is, it is well documented and what more can you ask for?

first check the condition the string is empty() or not.

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

}

then your problem will be solved.

but still one more problem is you pass negative values like

str = "-1";

StringUtils.isNumeric(str) it will be false.

You need to take care for this condition.

There is another solution. NumberUtils.isNumber This checks if it is a number either Long, Double, Integer.

Hope this help

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top