[enhanced enums] - end of the road?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jun 15 13:55:14 UTC 2017


I get what you are saying. But I think this intermediate supertype feels 
too magic. After all, you're after a sneaky way to extend from an enum - 
which is not something you can do in the source code. If it was 
possible, then you could just add the supertype yourself

e.g.

enum Option {

D extends Generic<String>

...
}

where Generic would be defined as the translated code you wrote.

But since Generic cannot be written, you need to put that in the Option 
declaration, which seems untidy - in other words, if I look at the class 
declaration for Generic, there's nothing which tells me that it extends 
from Option, which is a big red herring IMHO (what if Generic is in a 
different sourcefile?). Also, you open up issues where changing your 
enum declaration is effectively changing the supertype of a (seemingly) 
unrelated class - meaning that if you have code outside which relied on 
that Generic class, you could break them w/o changing the definition of 
Generic.

That's why I think adding custom superinterfaces would be slightly 
tidier - as the information goes exactly in the place where you need it.


Regarding your point about casting with the 'get' method - well, it 
seems to me the cast would be internal to the API - so it's not 
something the client would see (e.g. the caller of 'get' would be able 
to pass the enum constant just fine).

Maurizio


On 15/06/17 14:07, Peter Levart wrote:
>
>
> On 06/15/2017 02:44 PM, Peter Levart wrote:
>>>
>>> enum Option implements Consumer<String> {
>>>    D implements Generic<String>("-d", ...) { ... }
>>>    PROC implements Generic<ProcOption>("-proc", ...) { ... }
>>>
>>>    ...
>>>
>>> }
>>>
>>> Which is not too terrible (in fact has been put forward by John as a 
>>> comment in the JEP [1]).
>>>
>>
>> This is similar, but not the same. In above example, Generic<T> is 
>> not a subtype of Option. It's just an interface implemented by 
>> constant's subclasses. So you can not access Option members via an 
>> instance of Generic<T>... Generic<T> therefore has to declare all the 
>> interesting methods that can then be implemented by Option. You also 
>> have to accompany this solution with "sealed" interfaces if you don't 
>> want other implementations of Generic<T> besides the enum constants...
>
> ...in addition, you can not access/modify elements of EnumMap<Option, 
> ...> using keys of type Generic<T> for example - you would have to 
> cast which is awkward given that your example use case:
>
> public Z get(Generic<Z> option) { ... }
>
> ...would probably do just that...
>
> Regards, Peter
>



More information about the amber-spec-experts mailing list