Reg: Proposal: Generalized Number.parseNumber(String) Method for Java
Sathish Kumar Thiyagarajan
sathishkumar.thiyagarajan at gmail.com
Sat Mar 29 04:35:55 UTC 2025
Hi Kevin and Joseph,
Thank you both for your detailed insights. I really appreciate the
perspective you’ve shared on the limitations of Number
<https://docs.oracle.com/javase/8/docs/api/java/lang/Number.html> and the
challenges in evolving it.
I agree that modifying core classes may not be the right approach, given
the inherent constraints of Number. However, would it make sense to capture
these common patterns in a utility class instead?
> For example, File
> <https://docs.oracle.com/javase/8/docs/api/java/io/File.html> handling
> was significantly simplified with the Files
> <https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html>
> utility class, which introduced commonly used functionalities like copying,
> moving, and reading files. Could we follow a similar approach for numerical
> operations by introducing a Numbers utility class that provides
> frequently needed conversions and optimizations?
Would love to hear your thoughts on whether such an approach would be
useful and where it might fit within the broader discussion around numeric
types in Java.
Best regards,
Sathish Kumar Thiyagarajan
On Sat, 29 Mar 2025 at 00:37, Joseph D. Darcy <joe.darcy at oracle.com> wrote:
> Another reaction: in practice there is not much numeric about
> java.lang.Number. Operationally the type means "convertible to a primitive
> type" and there is nothing else extending Number lets you do with a class.
> Additionally in retrospect, Number would have been better as an interface
> rather than an abstract class.
>
> When looking to augment numeric capabilities of the platform, directly
> involving java.lang.Number is not the first or second place I'd look.
>
> Cheers,
>
> -Joe
>
> On 3/28/2025 11:38 AM, Kevin Bourrillion wrote:
>
> I appreciate you raising this; I think it is relevant to some internal
> discussions we’re having about the future of Number. Here’s some personal
> reactions from a team member (not a team consensus opinion):
>
> Unfortunately, we’ve found many times that `Number` is a pretty deficient
> return type that users can’t do much of anything useful with (except apply
> arbitrarily lossy conversions to, or test with `instanceof`).
>
> And I’m skeptical that most users ever want to end up in a situation where
> they have a `Number[]` or `Collection<Number>` that could be heterogeneous.
> This state feels like a temporary one you want to get out of.
>
> It’s not clear that `Number` can really be rehabilitated much, either. It
> is sort of a “deficient type” by its nature.
>
> When you do need this sort of flexible parsing, I think the status quo is:
> you can always parse to BigDecimal first, then ask questions about what
> more “minimal” type the value you got might fit into. Obviously this does
> not have optimal performance, but I am not sure there’s a good spot-fix
> here that doesn’t just raise more issues than it tried to resolve.
>
> We will keep thinking about this, though. Valhalla means we will
> inevitably have more "numeric types" than ever, and this is prompting us to
> think about what these types should have in common. (It’s a big topic and I
> apologize for not even attempting to outline it all for you here yet.)
>
>
>
> On Mar 28, 2025, at 10:29 AM, Sathish Kumar Thiyagarajan
> <sathishkumar.thiyagarajan at gmail.com>
> <sathishkumar.thiyagarajan at 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
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20250329/2fa266a3/attachment.htm>
More information about the core-libs-dev
mailing list