Minor improvement to anonymous classes

Tagir Valeev amaembo at gmail.com
Sat Jul 31 03:55:47 UTC 2021


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.
2. Allow new {...} instead of new Object() {...}.

So the specification roughly should be like this:
new <superclass_spec>, <interface1>, <interface2>,... {...}
<superclass_spec> = <superclass>(<constructor_arguments>)
<superclass_spec> could be omitted if it's java.lang.Object()
(for compatibility) if there's exactly one interface and
superclass_spec is omitted, it's allowed to put round parentheses
after the interface name.

With best regards,
Tagir Valeev.

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-observers mailing list