[enhanced enums] - end of the road?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jun 15 14:53:49 UTC 2017



On 15/06/17 15:43, Peter Levart wrote:
> Hi Maurizio,
>
> On 06/15/2017 03:55 PM, Maurizio Cimadamore wrote:
>> 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?).
>
> The constraint would be that Generic can only be in the same 
> compilation unit - i.e. as a static member class of the enum which 
> designates it as a super type of constants. But I see your point - it 
> would not have an "extends Option" clause in its declaration (the enum 
> declaration would designate it as a subclass of enum type from the 
> other way around), so it would be easy to misinterpret it.
>
>> 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
>
> ...yeah, but the implementation of get would have to cast, meaning 
> that there's something inadequate with the representation. Generics 
> were meant to reduce the need of explicit casts.
>
> I think there is a solution though which does not even require sealed 
> interfaces. Take your example with Generic<T> as plain interface:
>
> enum Option {
>    D implements Generic<String>("-d", ...) { ... }
>    PROC implements Generic<ProcOption>("-proc", ...) { ... }
>
>    ...
>
> }
>
>
> ...and then use the following method signature:
>
> public <Z, O extends Option & Generic<Z>> Z get(O option) { ... }
>
>
Yes - that's even better :-)

Maurizio
> Regards, Peter
>
>
>>
>>
>> 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