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