尹茂椿萱 created LANG-1822:
--------------------------
Summary: Inconsistency between NumberUtils.isCreatable and
createNumber
Key: LANG-1822
URL: https://issues.apache.org/jira/browse/LANG-1822
Project: Commons Lang
Issue Type: Bug
Affects Versions: 3.20.0
Reporter: 尹茂椿萱
There is an inconsistency between:
* {{NumberUtils.isCreatable(String)}}
* {{NumberUtils.createNumber(String)}}
Specifically, {{isCreatable}} returns {{true}} for certain numeric strings, but
{{createNumber}} fails to parse the same input and throws a
{{{}NumberFormatException{}}}.
Additionally, there are cases where {{createNumber}} successfully parses a
string, but {{isCreatable}} returns {{{}false{}}}.
This violates the expected contract:
{quote}If {{isCreatable(str)}} returns {{{}true{}}}, then {{createNumber(str)}}
should successfully return a {{{}Number{}}}.
{quote}
h2. Steps to Reproduce
{{@Test
public void test() \{
System.out.println(NumberUtils.isCreatable("#10"));
Number number = NumberUtils.createNumber("#10");
System.out.println(number.longValue());
System.out.println(NumberUtils.isCreatable("+1l"));
Number number1 = NumberUtils.createNumber("+1l");
System.out.println(number1.longValue());
}}}
----
h2. Actual Results
{{false
16
true
Exception in thread "main" java.lang.NumberFormatException: +1l is not a valid
number.}}
----
h2. Expected Results
h3. Case 1: {{"#10"}}
* Either:
** {{isCreatable("#10")}} should return {{{}true{}}},
* Or:
** {{createNumber("#10")}} should throw an exception
h3. Case 2: {{"+1l"}}
* Since {{{}isCreatable("+1l") == true{}}}, then:
** {{createNumber("+1l")}} should successfully return a {{Number}} (e.g.,
{{{}Long{}}})
----
h2. Analysis
h3. Issue 1: Hex format inconsistency
* {{"#10"}} is interpreted as a hexadecimal number ({{{}16{}}}) by
{{createNumber}}
* But {{isCreatable("#10")}} returns {{false}}
→ {{isCreatable}} does not recognize {{{}#{}}}-prefixed hexadecimal numbers,
while {{createNumber}} does
----
h3. Issue 2: Signed long literal inconsistency
* {{"+1l"}} is considered creatable ({{{}true{}}})
* But {{createNumber}} throws {{NumberFormatException}}
→ {{isCreatable}} accepts the format, but {{createNumber}} cannot parse it
----
h2. Impact
* Breaks API consistency
* Makes {{isCreatable}} unreliable as a validation method
* Can lead to unexpected runtime exceptions
Typical unsafe usage pattern:
{{if (NumberUtils.isCreatable(str)) \{
Number n = NumberUtils.createNumber(str); // may throw exception
}}}
----
h2. Suggested Fix
Ensure both methods follow consistent parsing rules:
h3. Option 1 (Preferred)
* Align {{createNumber}} with {{isCreatable}}
** Support:
*** {{+}} prefix combined with {{l/L}} suffix
*** {{#}} hexadecimal notation
h3. Option 2
* Restrict {{isCreatable}} to match {{createNumber}}
** Return {{false}} for:
*** {{"+1l"}}
*** {{"#10"}}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)