<!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>(Adding compiler-dev and dropping core-libs-dev)</p>
    <p>I think the compiler is correct here.</p>
    <p>In the first example, you call List::stream() on a raw List
      (because "c" has the raw type Child, so "c.getValues()" returns a
      raw list). This gives you a raw stream (Stream), which means the
      Stream::collect is also erased, meaning it just returns Object.
      But since the method return type is String, you get an error as
      Object cannot be returned if a String type is expected.</p>
    <p>In the second example you also first stash the result of
      "c.getValues()" (again, a raw list) into a variable of type
      List<String>. This is an unchecked operation -- as you are
      unsafely adding generic type parameters to raw type. The compiler
      lets you do it, with a warning. From that point on, it's as if
      there's no raw types. You have a List<String>, so calling
      List::stream gives you a Stream<String>. Which means
      Stream::collect no longer has an erased type, and a String is
      returned from the collect call, as expected. So you get a warning
      for the unchecked operation above, but then no errors.</p>
    <p>I hope this helps understanding what is going on.</p>
    <p>Maurizio<br>
    </p>
    <div class="moz-cite-prefix">On 10/06/2025 16:50, Jean-Noël
      Rouvignac wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CABw-sUJXEOm2AMkKT2Dp3sPDS=up3jgzRG4Rcd6rZ+wZB69JiQ@mail.gmail.com">
      <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>
    <ul class="dropdown-menu textcomplete-dropdown" style="display: none; position: absolute; z-index: 1000; left: 579.45px; top: 143px; bottom: auto;" contenteditable="false" popover="auto" data-strategy="emoji">
    </ul>
    <ul class="dropdown-menu textcomplete-dropdown" style="display: none; position: absolute; z-index: 1000;" contenteditable="false" popover="auto">
    </ul>
  </body>
</html>