Minor improvement to anonymous classes

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


----- Original Message -----
> From: "Tagir Valeev" <amaembo at gmail.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 05:55:47
> Subject: Re: Minor improvement to anonymous classes

> By the way, assuming that we implement this, new IFace() {...} would
> be technically equivalent to new Object(), IFace {...}. So this
> essentially means that specifying the Object superclass is optional
> "when interface is present". We can go a little bit further:
> 
> 1. Allow new IFace {...}, without empty parentheses, as there's
> technically no constructor in the interface we are delegating to.
> Instead, we are delegating to the Object constructor, but Object is
> not mentioned explicitly, so these () always looked confusing to me.
> We will still allow new IFace() {...} for compatibility.

It's not only confusing for you, it's confusing for my students too,
how the compiler is able to call the constructor of an interface is a question i get each year.

> 
> With best regards,
> Tagir Valeev.

Rémi

> 
> On Sat, Jul 31, 2021 at 10:44 AM Tagir Valeev <amaembo at gmail.com> wrote:
>>
>> I support this suggestion. I stumbled upon this problem many times.
>> Kotlin allows such declarations [1]
>> object : AbstractFoo(args), RedFoo {...}
>> Seems there's no conceptual difficulties with this enhancement.
>>
>> With best regards,
>> Tagir Valeev.
>>
>> [1] https://kotlinlang.org/spec/expressions.html#object-literals
>>
>> On Fri, Jul 30, 2021 at 9:53 PM 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