> From: "Kevin Bourrillion" <kev...@google.com>
> To: "Maurizio Cimadamore" <maurizio.cimadam...@oracle.com>
> Cc: "Brian Goetz" <brian.go...@oracle.com>, "amber-spec-experts"
> <amber-spec-experts@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.cimadam...@oracle.com | maurizio.cimadam...@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:kev...@google.com |
> kev...@google.com ]

Reply via email to