<div dir="ltr"><p class="gmail-">Hi Kevin and Joseph,</p>
<p class="gmail-">Thank you both for your detailed insights. I really appreciate the perspective you’ve shared on the limitations of <code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Number.html">Number</a></code> and the challenges in evolving it.</p>
<p class="gmail-">I agree that modifying core classes may not be the right approach, given the inherent constraints of <code>Number</code>. However, would it make sense to capture these common patterns in a utility class instead?</p>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">For example, <a href="https://docs.oracle.com/javase/8/docs/api/java/io/File.html">File</a> handling was significantly simplified with the <code><a href="https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html">Files</a></code> 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 <code>Numbers</code> utility class that provides frequently needed conversions and optimizations?</blockquote>
<p class="gmail-">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.</p>
<p class="gmail-">Best regards,<br>
Sathish Kumar Thiyagarajan</p></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Sat, 29 Mar 2025 at 00:37, Joseph D. Darcy <<a href="mailto:joe.darcy@oracle.com">joe.darcy@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>

  
  <div>
    <div>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.<br>
      <br>
      When looking to augment numeric capabilities of the platform,
      directly involving java.lang.Number is not the first or second
      place I'd look.</div>
    <div><br>
    </div>
    <div>Cheers,<br>
    </div>
    <div><br>
    </div>
    <div>-Joe<br>
    </div>
    <div><br>
    </div>
    <div>On 3/28/2025 11:38 AM, Kevin
      Bourrillion wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div>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):</div>
      <div><br>
      </div>
      <div>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`).</div>
      <div><br>
      </div>
      <div>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.</div>
      <div><br>
      </div>
      <div>It’s not clear that `Number` can really be rehabilitated
        much, either. It is sort of a “deficient type” by its nature.</div>
      <div><br>
      </div>
      <div>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.</div>
      <div><br>
      </div>
      <div>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.)</div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div><br>
        <blockquote type="cite">
          <div>On Mar 28, 2025, at 10:29 AM, Sathish Kumar Thiyagarajan
            <a href="mailto:sathishkumar.thiyagarajan@gmail.com" target="_blank"><sathishkumar.thiyagarajan@gmail.com></a> wrote:</div>
          <br>
          <div>
            <div dir="ltr">
              <p>Dear Core-Libs Dev Team,</p>
              <p><strong>Note:</strong> I have now subscribed to the
                mailing list and am resending this message as advised.</p>
              <p>I would like to propose an improvement to the JDK: a <strong>generalized
                  <code>
                    Number.parseNumber(String)</code> method</strong>.</p>
              <h3>Motivation</h3>
              <p>Java provides multiple number types (<code>byte</code>,
                <code>short</code>, <code>
                  int</code>, <code>long</code>, etc.), and developers
                typically choose them based on memory considerations.
                Currently, Java offers
                <code>String</code> to <code>Number</code> conversions
                using concrete classes:</p>
              <ul>
                <li>
                  <p><code>Long.parseLong(String)</code></p>
                </li>
                <li>
                  <p><code>Integer.parseInt(String)</code></p>
                </li>
                <li>
                  <p><code>Short.parseShort(String)</code>, etc.</p>
                </li>
              </ul>
              <p>While these are useful, Java lacks a <strong>generalized
                  method</strong> that returns the most memory-efficient
                <code>Number</code> representation based on the input,
                like:</p>
              <pre><code>Number.parseNumber(String numberAsText);
</code></pre>
              <h3>Use Case: JSON Serialization</h3>
              <p>This would be particularly useful in cases like <strong>JSON
                  serialization in REST APIs (Using <a href="https://github.com/FasterXML/jackson" target="_blank">Jackson</a>)</strong>, where
                number types are often altered during
                serialization/deserialization. Consider the following
                test case:</p>
              <pre><code>@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());
}
</code></pre>
              <h3>Reference Implementation</h3>
              <p>Here’s a rough implementation to illustrate the idea:</p>
              <pre><code>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
        }
    }
}
</code></pre>
              <p>Would love to hear your thoughts on this proposal.
                Appreciate your feedback and guidance!</p>
              <p>Thanks & Regards,<br>
                Sathish Kumar Thiyagarajan</p>
            </div>
          </div>
        </blockquote>
      </div>
      <br>
    </blockquote>
    <p><br>
    </p>
  </div>

</blockquote></div>