[enhanced enums] - end of the road?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jun 15 17:15:37 UTC 2017


Again, I see where you are trying to go, but ultimately it feels a bit 
ad hoc, because the class you mention in the 'extends' clause is given a 
special meaning, and is probably subject to extra restrictions  - it 
must have constructor in a certain shape, it cannot override methods 
like name() etc. - and, again, these restrictions simply do not make 
sense if you look at the 'Generic' class declaration only.

Stepping back, while having custom generic supertypes is a nice trick to 
associate type information to enum constants, I also believe that, in 
terms of expressiveness, it is not the same thing as having full generic 
enums which can declare their own generic members. Granted, the client 
might not care too much if the members he can access are the same 
(although in some cases the client will have to use a different type 
than the enum one), but in terms of reading the resulting code (in which 
the state of the enum becomes spread across multiple places), I'm not 
sure if where we end up is better than where we started from.

Maurizio


On 15/06/17 17:12, Peter Levart wrote:
>
>
> On 06/15/2017 04:53 PM, Maurizio Cimadamore wrote:
>>> 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 
>
> ...but why stop there. Currently, it is not possible (in source code) 
> to subclass enum(s) even though they are not technically final because 
> constants can have custom subclasses. What is also enforced in source 
> is that enum constructor(s) are implicitly private and that they can 
> not be called explicitly. What if this subclassing constraint was 
> lifted, but just the subclassing constraint - enum constructor(s) 
> would still be enforced private and not explicitly callable except 
> when chained from subclass. What this would amount to is that enum(s) 
> could be subclassed by classes that are able to chain-call enum 
> constructors - enum member classes (anonymous or local enum subclasses 
> would be disallowed). If some enum member class subclassed the enum, 
> its constructor(s) would get additional implied 'name' and 'ordinal' 
> parameters and would fall under the same restriction as enum's 
> constructor(s) - they would be implicitly and enforced private and not 
> explicitly callable except when chained from subclass. This would 
> amount to the following possibility:
>
> public enum Option {
>
>     D extends Generic<String>("-d", "default"),
>     PROC extends Generic<ProcOption>("-proc", ProcOption.DEFAULT);
>
>     public class Generic<T> extends Option {
>
>         final T defaultValue;
>
>         /* private */ Generic(String opt, T defaultValue) {
>             super(opt);
>             this.defaultValue = defaultValue;
>         }
>     }
>
>     final String opt;
>
>     /* private */ Option(String opt) {
>         this.opt = opt;
>     }
> }
>
> ...the constants would optionally be able to extend any enum's 
> subclass and/or implement any additional interfaces. There could be 
> multiple enum subclasses (all constrained to be enum member classes) 
> and each constant could independently choose to extend any one of them 
> or none.
>
> What do you think of that?
>
> Regards, Peter
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20170615/38a36b32/attachment.html>


More information about the amber-spec-experts mailing list