I'm sorry that I appeared to be suggesting that there were no other reasons to suppress it. I was actually giving just one example. Nevertheless, the check has done more good than "harm" (in the form of these small suppression costs).
On Thu, Oct 7, 2021 at 2:08 PM Remi Forax <fo...@univ-mlv.fr> wrote: > > > ------------------------------ > > *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 < > 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) > > 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. |kev...@google.com > > -- Kevin Bourrillion | Java Librarian | Google, Inc. | kev...@google.com