2 questions about enums and the closed/withdrawn JEP 301

Brian Goetz brian.goetz at oracle.com
Wed Mar 29 02:45:01 UTC 2023


> 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 :)


More information about the amber-dev mailing list