2 questions about enums and the closed/withdrawn JEP 301

Red IO redio.development at gmail.com
Wed Mar 29 06:56:06 UTC 2023


I think if we are talking about the initial question again the elephant in
the room is the lack of a way to express subtypes in supertypes (F-bounds)
without using "hacks" like the recursive generic. That this (mis)use of
generics is confusing is demonstrated in this thread and in many others.
A good solution would be to introduce a "This" type that always refers to
the current class type even when inheriting. I'm by far not the first
person to suggest that.
But the bigger problem is that this ship has sailed for the Enum class.
Even if the This type was introduced now and used in Enum removing the
generic parameter would be a braking change to the Enum class braking every
code that relies on the parameter to be present.
The possibility to add This regardless of the Enum class should still be
considered thought.

Great regards
RedIODev

On Wed, Mar 29, 2023, 04:45 Brian Goetz <brian.goetz at oracle.com> wrote:

>
> > This somewhat clears it up. Are you basically saying that the only
> > reason why the supertype can know about the subtype is because the
> > relationship is recursive, and thus, the recursion allows the
> > supertype to "know" about the subtype because the subtype is just a
> > roundabout way of referencing itself - something the supertype DOES
> > have access to?
>
> F-bounds are weird-looking at first:
>
>      abstract class Enum<T extends Enum<T>> { ... }
>
> in part because it's not always obvious what "T" means at first. We're
> used to seeing type variables that represent element types (List<T>), or
> result types (Supplier<T>), but this T really means "subclass".  If it
> were written
>
>      abstract class Enum<Subclass extends Enum<Subclass>> { Subclass[]
> values(); }
>
> it would already be clearer.  You might first try writing it as
>
>      abstract class Enum<Subclass> { ... }
>
> but this permits extension in unexpected ways:
>
>      class FooEnum extends Enum<String> { ... }
>
> You could try refining it as
>
>      abstract class Enum<Subclass extends Enum> { ... }
>
> but this still permits
>
>      class FooEnum extends Enum<BarEnum> { ... }
>
> What we're trying to express is that the type argument of Enum *is* the
> class being declared.  Which is where the f-bound comes in:
>
>      abstract class Enum<Subclass extends Enum<Subclass>> { Subclass[]
> values(); }
>
> which can only be satisfied by a declaration of the form
>
>      class X extends Enum<X> { ... }
>
> The first few times you look at it, it seems weird and magic, and then
> at some point it seems obvious :)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20230329/df7f7e14/attachment.htm>


More information about the amber-dev mailing list