<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link id="MDHR_textcomplete" rel="stylesheet" href="moz-extension://aa8b6de7-3f78-465d-87c7-03091dbf00e6/vendor/textcomplete.css">
  </head>
  <body>
    <p>I've replied here (and moved the thread in compiler-dev) --
      please follow up there if anything feels missing:</p>
    <p><a class="moz-txt-link-freetext" href="https://mail.openjdk.org/pipermail/compiler-dev/2025-June/030756.html">https://mail.openjdk.org/pipermail/compiler-dev/2025-June/030756.html</a></p>
    <p>Maurizio<br>
    </p>
    <div class="moz-cite-prefix">On 10/06/2025 17:20, Éamonn McManus
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAChqX88R4kDimdLk-dKy3fR5s8kzgT4M6Vf=Y0sNxAVPuHNDgw@mail.gmail.com">
      
      <div dir="ltr">This question would probably be better asked on
        Stack Overflow or the like. The short answer is that the
        compiler is following the language spec. <a href="https://docs.oracle.com/javase/specs/jls/se24/html/jls-4.html#jls-4.8" moz-do-not-send="true">§4.8</a> says:<br>
        <p class="gmail-norm-static" style="color:rgb(0,0,0);font-size:12px">> The type of a
          constructor (<a class="gmail-xref" href="https://docs.oracle.com/javase/specs/jls/se24/html/jls-8.html#jls-8.8" title="8.8. Constructor Declarations" moz-do-not-send="true">§8.8</a>),
          instance method (<a class="gmail-xref" href="https://docs.oracle.com/javase/specs/jls/se24/html/jls-8.html#jls-8.4" title="8.4. Method Declarations" moz-do-not-send="true">§8.4</a>, <a class="gmail-xref" href="https://docs.oracle.com/javase/specs/jls/se24/html/jls-9.html#jls-9.4" title="9.4. Method Declarations" moz-do-not-send="true">§9.4</a>),
          or non-<code class="gmail-literal">static</code> field (<a class="gmail-xref" href="https://docs.oracle.com/javase/specs/jls/se24/html/jls-8.html#jls-8.3" title="8.3. Field Declarations" moz-do-not-send="true">§8.3</a>)
          of a raw type <span class="gmail-type">C</span> that is not
          inherited from its superclasses or superinterfaces is the
          erasure of its type in the generic class or interface <span class="gmail-type">C</span>.</p>
        It <i>doesn't</i> say that this only applies when the original
        type references the type parameters that have been omitted from
        the raw type. So the return type of getValues() in the raw Child
        is raw List, even though the original type List<String>
        doesn't mention T.</div>
      <br>
      <div class="gmail_quote gmail_quote_container">
        <div dir="ltr" class="gmail_attr">On Tue, 10 Jun 2025 at 08:50,
          Jean-Noël Rouvignac <<a href="mailto:jean-noel.rouvignac@pingidentity.com" moz-do-not-send="true" class="moz-txt-link-freetext">jean-noel.rouvignac@pingidentity.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">
          <div dir="ltr">
            <div>Hello,</div>
            <div><br>
            </div>
            <div>When doing refactorings to take advantage of newer Java
              features, I hit a new and weird edge case. I trimmed down
              the code several times, and ended up with the following
              tiny reproducer, and I don't understand what javac is
              complaining about even with javac 24:<br>
              <div>
                <div><br>
                </div>
                <div>(Note: unlike the original code, this reproducer is
                  very contrived, so there's no need to make comments on
                  how bad it is: I fully agree)</div>
              </div>
              <br>
              ```java<br>
              1 import java.util.ArrayList;<br>
              import java.util.List;<br>
              import java.util.stream.Collectors;<br>
              <br>
              public class Main {<br>
                  private static final class Child<T> {<br>
                      public List<String> getValues() {<br>
                          return new ArrayList<>();<br>
                      }<br>
                  }<br>
              <br>
                  @SuppressWarnings("unchecked")<br>
                  private static String getString1(Child c) {<br>
                      // Compilation error:<br>
                      // Main.java:16: error: incompatible types: Object
              cannot be converted to String<br>
                      return
              c.getValues().stream().collect(Collectors.joining());<br>
                  }<br>
              <br>
                  private static String getString2(Child c) {<br>
                      // Compilation error:<br>
                      // Main.java:27: warning: [unchecked] unchecked
              conversion<br>
                      //        List<String> values =
              c.getValues();<br>
                      //                                         ^<br>
                      //  required: List<String><br>
                      //  found:    List<br>
                      //1 warning<br>
                      List<String> values = c.getValues();<br>
                      return
              values.stream().collect(Collectors.joining());<br>
                  }<br>
              }<br>
              ```<br>
              <br>
              It turns out IntelliJ is a bit more eloquent than javac,
              and when hovering over the warning on `c.getValues()` at
              the line with `List<String> values =
              c.getValues();`, it reports the following:<br>
              <br>
              >    Unchecked assignment: 'java.util.List' to
              'java.util.List<java.lang.String>'. Reason: 'c' has
              raw type, so result of getValues is erased <br>
              <br>
            </div>
            <div>Is it possible that javac is doing early type erasure
              when analysing this code, erasing a bit too much? Even if
              the code uses `Child` without type argument, I would
              expect the return type of `getValues()` to be well defined
              as `List<String>`?<br>
              <br>
            </div>
            <div>What do you think?<br>
            </div>
            <div>I am sure there is some rational explanation that I
              missed for this behaviour. I could not find a JBS issue
              showing the same case as here.</div>
            <div><br>
            </div>
            <div>Thank you,</div>
            <div>Jean-Noël Rouvignac</div>
          </div>
          <br>
          <i style="margin:0px;padding:0px;border:0px;outline:0px;vertical-align:baseline;background:rgb(255,255,255);font-family:proxima-nova-zendesk,system-ui,-apple-system,system-ui,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",Arial,sans-serif;color:rgb(85,85,85)"><span style="margin:0px;padding:0px;border:0px;outline:0px;vertical-align:baseline;background:transparent;font-family:proxima-nova-zendesk,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",Arial,sans-serif;font-weight:600"><font size="2">CONFIDENTIALITY NOTICE: This email may contain
                confidential and privileged material for the sole use of
                the intended recipient(s). Any review, use, distribution
                or disclosure by others is strictly prohibited.  If you
                have received this communication in error, please notify
                the sender immediately by e-mail and delete the message
                and any file attachments from your computer. Thank you.</font></span></i></blockquote>
      </div>
    </blockquote>
    <ul class="dropdown-menu textcomplete-dropdown" style="display: none; position: absolute; z-index: 1000;" contenteditable="false" popover="auto">
    </ul>
  </body>
</html>