Minor improvement to anonymous classes

Remi Forax forax at univ-mlv.fr
Sat Jul 31 18:24:47 UTC 2021


----- Original Message -----
> From: "John Rose" <john.r.rose at oracle.com>
> To: "Brian Goetz" <brian.goetz at oracle.com>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Sent: Samedi 31 Juillet 2021 00:14:46
> Subject: Re: Minor improvement to anonymous classes

> It seems reasonable:  If you can do this for lambdas,
> which are (sort of) a concise anonymous inner class
> notation, you should be able to do this with the next
> level of notation, anonymous inner classes.  It’s
> ungraceful to have MI on lambdas and named inner
> classes, but not the intermediate notation.
> 
> Any similar limitations to consider loosening at this time?
> Are there things with generics you can do with lambdas
> and named ICs but not AICs?

There is a similar limitation, anonymous classes and local classes always capture the enclosing "this" even if they do not use it,
so when you use an anonymous class, the lifetime of the enclosing this is extended for no good reason.
The usual issue it to have a code that relies on the finalizer to close a system resource (which is not a good idea) that fails to close the resource because the is captured by the anonymous class. Lambdas do not have this weird behavior.

We have discussed about allowing static in front of a local class but there is no way to ask for a static anonymous class.

regards,
Rémi


> 
>> On Jul 30, 2021, at 7:52 AM, Brian Goetz <brian.goetz at oracle.com> wrote:
>> 
>> I have been working on a library where I've found myself repeatedly refactoring
>> what should be anonymous classes into named (often local) classes, for the sole
>> reason that I want to combine interfaces with an abstract base class:
>> 
>>     interface Foo { ... lots of stuff .. }
>>     abstract class AbstractFoo { ... lots of base implementation ... }
>> 
>>     interface RedFoo extends Foo { void red(); }
>> 
>> and I want a factory that yields a RedFoo that is based on AbstractFoo and
>> implements red().  Trivial with a named class, but there's no reason I should
>> not be able to do that with an anonymous class, since I have no need of the
>> name.
>> 
>> We already address this problem elsewhere; there are several places in the
>> grammar where you can append additional _interfaces_ with &, such as:
>> 
>>     class X<T extends Foo & Red> { ... }
>> 
>> and casts (which can be target types for lambdas.)
>> 
>> These are not full-blown intersection types, but accomodate for the fact that
>> classes have one superclass and potentially multiple interfaces.  It appears
>> simple to extend this to inner class creation expressions:
>> 
>>     new AbstractFoo(args) & RedFoo { ... }
>> 
>> This would also smooth out a rough edge refactoring between lambdas and
>> anonymous classes.
>> 
>> I suspect there are one or two other places in the spec that could use this
>> treatment.
>> 
>> (Note that this is explicitly *not* a call for "let's do full-blown intersection
>> types"; this is solely about class declaration.)
>> 


More information about the amber-spec-experts mailing list