[
https://issues.apache.org/jira/browse/LANG-1822?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Gary D. Gregory resolved LANG-1822.
-----------------------------------
Fix Version/s: 3.21.0
Resolution: Fixed
Hello [~buzhiweihe]
The 2 APIs should now be consistent in git master and snapshot builds in
https://repository.apache.org/content/repositories/snapshots/org/apache/commons/commons-lang3/3.21.0-SNAPSHOT/
Please verify your use case and close this ticket if appropriate.
Thank you!
> 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: 尹茂椿萱
> Priority: Major
> Fix For: 3.21.0
>
>
> 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)