Minor improvement to anonymous classes
Remi Forax
forax at univ-mlv.fr
Thu Oct 7 21:08:48 UTC 2021
> From: "Kevin Bourrillion" <kevinb at google.com>
> To: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>
> Cc: "Brian Goetz" <brian.goetz at oracle.com>, "amber-spec-experts"
> <amber-spec-experts at openjdk.java.net>
> Sent: Jeudi 7 Octobre 2021 22:37:58
> Subject: Re: Minor improvement to anonymous classes
> On Thu, Oct 7, 2021 at 7:37 AM Maurizio Cimadamore < [
> mailto:maurizio.cimadamore at oracle.com | maurizio.cimadamore at oracle.com ] >
> wrote:
>> <X extends Foo & AutoCloseable> X getCloseableFoo();
>> Which kind of works, but it's quite an horrible hack (you introduce a type
>> parameter you don't need - which means compiler will try to infer types, etc.)
> (Incidentally, we have Error Prone give a warning any time a method/constructor
> type parameter is unused in any of the formal parameter types, and I think the
> results have been good. A method like `emptySet()` has to suppress it, but it's
> a fairly special case.)
Using an "unused" parameter types as return type is not unusual either when returning null or when throwing an exception given that both the type of null and the "nothing" type can not be expressed in Java.
See by example the javadoc of Assertions.fail()
[ https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/Assertions.html#fail(java.lang.String) | https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/Assertions.html#fail(java.lang.String) ]
The other usage i can see is to have a better type inference of the return type (avoid an explicit cast) when using a polymorphic signature but i'm not even sure javac support it.
RĂ©mi
>> On 30/07/2021 15:52, Brian Goetz 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.)
> --
> Kevin Bourrillion | Java Librarian | Google, Inc. | [ mailto:kevinb at google.com |
> kevinb at google.com ]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20211007/6af99632/attachment-0001.htm>
More information about the amber-spec-experts
mailing list