Anonymous class instance creation expression with diamond compatibility constraint is reduced to anonymous class type?

B. Blaser bsrbnd at gmail.com
Mon Mar 13 14:13:47 UTC 2017


On 13 March 2017 at 13:00, B. Blaser <bsrbnd at gmail.com> wrote:
> Hi,
>
> On 13 March 2017 at 08:54, Srikanth <srikanth.adayapalam at oracle.com> wrote:
>> https://bugs.openjdk.java.net/browse/JDK-8133936 seems to have some wordings
>> that explains the
>> rationale.
>>
>> Srikanth
>
> There is a small difference between Georgiy's example and jdk 8133936
> as shown in the commented example here under.
>
> Georgiy's said:
>
> "4. Unchecked conversion is necessary in order for constructor Foo to be
> applicable so the return type D is erased and should be Foo."
>
> Which relates to Daniel's comment on jdk 8133936:
>
> "If C is an anonymous class, then the chosen constructor is the constructor of
> the anonymous class. The return type is the anonymous class type."
>
> Then:
> - in Georgiy's example, the constructor's return type is chosen (due
> to unchecked conversion) and javac fails.
> - in jdk 8133936 example, the mj's return type is chosen and javac succeeds.
>
> The question is:
> - Is this right to use the constructor's return type in Georgiy's
> example instead of mj's return type?

To resume:
- if Foo isn't generic (or erased), the constructor's return type
<anonymous Foo> is used. For example:

    class Foo {}
    m2(new List<Foo>(), m1(new Foo(){ }).getThis());

  also fails to compile.

- if Foo is generic, the mj's return type Foo<String> is used.

Which seems to be compliant with JLS 15.9.3; but the behavior isn't
absolutely orthogonal between generic and non-generic types as it
seems to be driven by inference needs... See Daniel's comment on jdk
8133936:

"This is pretty messy, but there's a reason for it: we can't really talk about a
class type '[anonymous Foo<___>]' until we can fill in the blank."

Bernard

> class List<T> {
>     List() {}
>     List<T> getThis() {
>         return new List();
>     }
> }
> class MyType<T> {}
> class Foo<T> {
> //    public Foo(T a1){}
>     public Foo(MyType<String> a1){}
> }
> public class Test25 {
>     public static <T> List<T> m1(T item) {
>         List l = new List();
>         return l;
>     }
>     public static <U> void m2(List<U> list1, List<U> list2) { }
>     public static void test() {
> //        m2(new List<Foo<String>>(), m1(new Foo<>("str"){ }).getThis());
>         m2(new List<Foo>(), m1(new Foo<>(new MyType()){ }).getThis());
>     }
> }


More information about the compiler-dev mailing list