Diamond with anonymous classes: what if anonymous class were generic

Remi Forax forax at univ-mlv.fr
Wed Jun 24 19:02:03 UTC 2015


Hi Georgiy,

On 06/24/2015 03:51 PM, Georgiy Rakov wrote:
> It's not the bug or issue what I'm asking about. I'm asking about, 
> say, alternative approach to anonymous classes.
>
> Current approach defined by JLS specifies
> that when super type of the anonymous class is generic and explicit 
> type arguments or diamond is used in the instance creation expression
> then corresponding anonymous class declaration is declared 
> (implicitly) _as NOT generic_. This is not explicitly specified by JLS 
> but if I understand correctly it happens so in fact.
> For instance if we consider the example below.
>
>     class Foo<T> {
>     }
>
>     Foo<String> inst = new Foo<String>(){};
>
> The declaration of the anonymous class above is identical to the 
> following one:
>
>     class 1 extends Foo<String> {} //let's imagine that "1" is a valid
>     identifier
>
> And the type of the instance creation expression is 1.
>
> But one can imagine another approach which might be defined by spec 
> and which would specify
> that when super type of the anonymous class is generic and explicit 
> type arguments or diamond is used in the instance creation expression
> then corresponding anonymous class declaration is declared 
> (implicitly) _as generic_. In this case type arguments from its super 
> type would be "derived" by anonymous class declaration.
> For instance if we consider the example presented above the 
> declaration of the anonymous class would be identical to following one:
>
>     class 1<T> extends Foo<T> {} //let's again imagine that "1" is a
>     valid identifier
>
> And the type returned by the instance creation expression would be: 
> 1<String>.
>
> I'm just wondering if you considered such approach.
>
> It seems that provided this approach were implemented there would be 
> no needs for exceptions specified by following assertions:
>
>     ***It is a compile-time error if the superclass or superinterface
>     type of the anonymous class, T, or any subexpression of T, has one
>     of the following forms:
>     - A type variable (4.4) that was not declared as a type parameter
>     (such as a type variable produced by capture conversion (5.1.10))
>     - An intersection type (4.9)
>     - A class or interface type, where the class or interface
>     declaration is not accessible from the class or interface in which
>     the expression appears.***
>     The term "subexpression" includes type arguments of parameterized
>     types (4.5), bounds of wildcards (4.5.1), and element types of
>     array types (10.1). It excludes bounds of type variables.***
>
> Thanks,
> Georgiy.

It's a very good question :)
The problem of the approach you suggest is that because a type variable 
is considered as its bound your proposal has not the same semantics has 
the one specified by the JLS.

By example,
   class A<T> {
      T t;

      void foo(Object o) { ... }
      void foo(String s) { ... }

      void bar() {
         new A<String>() {{
           foo(t);   // should call foo(String) and not foo(Object)
         }};
      }
   }

with your semantics, new A<String> is equivalent to new $1<T> extends 
A<T> then T = String,
so 't' is considered as an Object, the bound of T, so foo(t) will call 
foo(Object) and not foo(String).

regards,
Rémi

>
> On 23.06.2015 11:51, Srikanth wrote:
>>
>>
>> On Thursday 11 June 2015 08:02 PM, Georgiy Rakov wrote:
>>> Hello,
>>>
>>> currently when diamond is used in anonymous class instance creation 
>>> expression the class being instantiated is not generic. I believe 
>>> this is the reason why there are exceptions specified in the 
>>> assertion below:
>>>
>>>     ***It is a compile-time error if the superclass or
>>>     superinterface type of the anonymous class, T, or any
>>>     subexpression of T, has one of the following forms:
>>>     - A type variable (4.4) that was not declared as a type
>>>     parameter (such as a type variable produced by capture
>>>     conversion (5.1.10))
>>>     - An intersection type (4.9)
>>>     - A class or interface type, where the class or interface
>>>     declaration is not accessible from the class or interface in
>>>     which the expression appears.***
>>>     The term "subexpression" includes type arguments of
>>>     parameterized types (4.5), bounds of wildcards (4.5.1), and
>>>     element types of array types (10.1). It excludes bounds of type
>>>     variables.***
>>>
>>> What if the anonymous class declaration derived the type parameters 
>>> from the type specified in the instance creation expression (from 
>>> super type). In this case the anonymous class would be a generic 
>>> class and the type of the instance created will be a regular 
>>> parameterization of that generic class. In this case I believe the 
>>> situation will be identical to ordinary non-anonymous classes and 
>>> there would be no needs to specify inferred types in the class 
>>> signature.
>>>
>> Georgiy,
>>
>> I am not sure I entirely understand what you are saying here - There 
>> is no notion of an anonymous class declaration "deriving" its type 
>> parameters from its super type. Neither the compiler nor the JLS view 
>> the anonymous
>> class as being generic and "type of the instance created will be a 
>> regular parameterization of that generic class".
>>
>> Do you have in mind some code that you think should not be compiled, 
>> but  is or should be but is not ?
>>
>> Is that what the code snippet below is supposed be ???
>>
>> class Foo<T> {
>> }
>>
>>
>> Foo<String> inst = new Foo<>(){};
>>
>> In this case, the anonymous type's super type is Foo<String> and I 
>> don't see an issue here.
>>
>> Thanks!
>> Srikanth
>>
>>
>>
>>> For instance:
>>>
>>>     class Foo<T> {ge
>>>     }
>>>
>>>     Foo<String> inst = new Foo<>(){};
>>>
>>> Here anonymous class would have type parameter T derived from its 
>>> super type T. The type of instance creation expression will be the 
>>> parameterization of this generic anonymous class with T inferred as 
>>> String.
>>>
>>> I wonder if you considered such option.
>>>
>>> Thank you,
>>> Georgiy.
>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20150624/3b621f8a/attachment-0001.html>


More information about the compiler-dev mailing list