Sure, Volkan. Let me explain with a sample use case (I also have the source code available on GitHub at https://github.com/sathishk/parse-number ).
> When developing *REST APIs or Data Engineering applications*, we often > deal with *untyped JSON documents*, which are loaded into Java as Map<String, > Object> (for JSON objects) or List<Object> (for JSON arrays). Typically, > JSON parsers convert these into Java objects. Consider this example: Map<String, Number> originalData = Map.of( "byteValue", (byte) 123, "shortValue", (short) 1234 ); This would be represented as the following JSON: { "shortValue": 1234, "byteValue": 123 } Now, when we *deserialize* this JSON using a parser like Jackson <https://www.baeldung.com/java-json-maps-comparison#1-using-jackson>: Map<String, Object> deserializedData = new JsonReader().getJacksonMap(jsonString); The expectation is that *numeric values should be preserved in their smallest possible type* (byte or short). However, *Jackson (and most JSON parsers) default to Integer for whole numbers* because they rely on Integer.parseInt(String), which is a safe fallback for most cases. Why Number.parseNumber(String)? If we had a *generalized Number.parseNumber(String) method*, it could intelligently determine the most memory-efficient number type based on the value range. This would help reduce unnecessary memory usage, especially when handling large datasets in *high-performance applications*. Would love to hear your thoughts on this approach! Thanks & Regards, Sathish Kumar Thiyagarajan On Mon, 31 Mar 2025 at 14:56, Volkan Yazıcı <vol...@yazi.ci> wrote: > Sathish, would you mind elaborating on your use case a bit more, please? > That is, I am not able to see where and how you want to leverage > `Number#parseNumber(String)` in the `testNumberMemoryUsage()` method. > Example: *"I have this test method verifying this behavior of that > application. Given a `Number#parseNumber(String)`, I can improve this as > follows."* > > On Fri, Mar 28, 2025 at 6:31 PM Sathish Kumar Thiyagarajan < > sathishkumar.thiyagara...@gmail.com> wrote: > >> Dear Core-Libs Dev Team, >> >> *Note:* I have now subscribed to the mailing list and am resending this >> message as advised. >> >> I would like to propose an improvement to the JDK: a *generalized >> Number.parseNumber(String) method*. >> Motivation >> >> Java provides multiple number types (byte, short, int, long, etc.), and >> developers typically choose them based on memory considerations. Currently, >> Java offers String to Number conversions using concrete classes: >> >> - >> >> Long.parseLong(String) >> - >> >> Integer.parseInt(String) >> - >> >> Short.parseShort(String), etc. >> >> While these are useful, Java lacks a *generalized method* that returns >> the most memory-efficient Number representation based on the input, like: >> >> Number.parseNumber(String numberAsText); >> >> Use Case: JSON Serialization >> >> This would be particularly useful in cases like *JSON serialization in >> REST APIs (Using Jackson <https://github.com/FasterXML/jackson>)*, where >> number types are often altered during serialization/deserialization. >> Consider the following test case: >> >> @Test >> void testNumberMemoryUsage() throws JsonProcessingException { >> ObjectMapper mapper = new ObjectMapper(); >> Map<String, Object> numbersObject = Map.of("aShort", (short) 1234, >> "aFloat", (float) 1.33); >> >> final String jsonText = mapper.writeValueAsString(numbersObject); >> Map<String, Object> parsedJsonObject = mapper.readValue(jsonText, new >> TypeReference<>() {}); >> >> // Expected: Short.class | Actual: Integer.class >> assertEquals(Short.class, parsedJsonObject.get("aShort").getClass()); >> >> // Expected: Float.class | Actual: Double.class >> assertEquals(Float.class, parsedJsonObject.get("aFloat").getClass()); >> } >> >> Reference Implementation >> >> Here’s a rough implementation to illustrate the idea: >> >> private static Number parseNumber(final String numberStr) { >> try { >> if (numberStr.contains(".")) { >> double doubleValue = Double.parseDouble(numberStr); >> return (doubleValue >= -Float.MAX_VALUE && doubleValue <= >> Float.MAX_VALUE) ? >> (float) doubleValue : doubleValue; >> } else { >> long longValue = Long.parseLong(numberStr); >> if (longValue >= Byte.MIN_VALUE && longValue <= Byte.MAX_VALUE) { >> return (byte) longValue; >> } else if (longValue >= Short.MIN_VALUE && longValue <= >> Short.MAX_VALUE) { >> return (short) longValue; >> } else if (longValue >= Integer.MIN_VALUE && longValue <= >> Integer.MAX_VALUE) { >> return (int) longValue; >> } else { >> return longValue; >> } >> } >> } catch (NumberFormatException e) { >> return parseBigNumber(numberStr); >> } >> } >> >> private static Number parseBigNumber(final String numberStr) { >> try { >> return new BigInteger(numberStr); // Try BigInteger first >> } catch (NumberFormatException e) { >> // Only create BigDecimal if BigInteger fails >> BigDecimal bd = new BigDecimal(numberStr); >> try { >> // Convert to BigInteger if there's no fraction >> return bd.toBigIntegerExact(); >> } catch (ArithmeticException ex) { >> return bd; // If it's a decimal, return BigDecimal >> } >> } >> } >> >> Would love to hear your thoughts on this proposal. Appreciate your >> feedback and guidance! >> >> Thanks & Regards, >> Sathish Kumar Thiyagarajan >> >