I've replied here (and moved the thread in compiler-dev) -- please follow up there if anything feels missing:

https://mail.openjdk.org/pipermail/compiler-dev/2025-June/030756.html

Maurizio

On 10/06/2025 17:20, Éamonn McManus wrote:
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. §4.8 <https://docs.oracle.com/javase/specs/jls/se24/html/jls-4.html#jls-4.8> says:

> The type of a constructor (§8.8 <https://docs.oracle.com/javase/specs/jls/se24/html/jls-8.html#jls-8.8>), instance method (§8.4 <https://docs.oracle.com/javase/specs/jls/se24/html/jls-8.html#jls-8.4>, §9.4 <https://docs.oracle.com/javase/specs/jls/se24/html/jls-9.html#jls-9.4>), or non-|static| field (§8.3 <https://docs.oracle.com/javase/specs/jls/se24/html/jls-8.html#jls-8.3>) of a raw type C that is not inherited from its superclasses or superinterfaces is the erasure of its type in the generic class or interface C.

It /doesn't/ 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.

On Tue, 10 Jun 2025 at 08:50, Jean-Noël Rouvignac <jean-noel.rouvig...@pingidentity.com> wrote:

    Hello,

    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:

    (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)

    ```java
    1 import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;

    public class Main {
        private static final class Child<T> {
            public List<String> getValues() {
                return new ArrayList<>();
            }
        }

        @SuppressWarnings("unchecked")
        private static String getString1(Child c) {
            // Compilation error:
            // Main.java:16: error: incompatible types: Object cannot
    be converted to String
            return c.getValues().stream().collect(Collectors.joining());
        }

        private static String getString2(Child c) {
            // Compilation error:
            // Main.java:27: warning: [unchecked] unchecked conversion
            //        List<String> values = c.getValues();
            //                                         ^
            //  required: List<String>
            //  found:    List
            //1 warning
            List<String> values = c.getValues();
            return values.stream().collect(Collectors.joining());
        }
    }
    ```

    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:

    >    Unchecked assignment: 'java.util.List' to
    'java.util.List<java.lang.String>'. Reason: 'c' has raw type, so
    result of getValues is erased

    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>`?

    What do you think?
    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.

    Thank you,
    Jean-Noël Rouvignac

    /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./

Reply via email to