JEP 301: Enhanced Enums

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Dec 7 11:58:54 UTC 2016


Thanks for your feedback. As with the other JEP (Lambda Leftovers) and 
all JEPs in general, nothing is set in stone (at least not at this 
stage). I hear that there are some concerns around allowing access to 
sharp members of an enum constants, but I'd like also to carefully weigh 
those concerns once a prototype implementation is available for general 
use. As I said in the other comment to Remi - we had this for anonymous 
inner classes for ages, but nobody really notices. The goal here is not 
to suggest people should start using enums to replace class/interface 
hierarchies, as it is to remove restrictions in the usage of enum 
constants. I believe there's a path for doing so which does not 
significantly alter neither source compatibility, binary compatibility 
nor the user model (you are still free to think that a sharp enum 
constant E.Foo has type E if you like - as you probably think that new 
Object() {} has type Object). Of course we can re-evaluate should 
usability issue pop up in real world examples.

Thanks
Maurizio


On 07/12/16 11:19, Stephen Colebourne wrote:
> As a motivating example, I considered this design for JSR-310, but had
> to reject it as this feature didn't exist:
>
> interface IntValue {
>    int intValue();
> }
>
> enum ChronoField<X extends IntValue> {
>    YEAR<Year>,
>    MONTH<Month>,
>    DAY_OF_MONTH<Integer>,
>    DAY_OF_WEEK<DayOfWeek>,
> }
>
> Year year = date.get(ChronoField.YEAR);
> Month month = date.get(ChronoField.MONTH);
> int dom = date.get(ChronoField.DAY_OF_MONTH);
>
> (Note however that this may well have been a bad idea anyway)
>
> However, IMO this proposal goes much further than the minimum
> necessary to support the above, and I cannot support the proposal as
> it stands. In particular, I am unconvinced that individual enum
> constants should have visible members - exposing the generic at the
> constant level is OK, but no more than that makes sense. This is
> because enums are deliberately intended as a limited feature, with
> subclasses of enums intended to be non-visible to the application
> (they are merely a convenience to avoid a switch-on-enum statement).
>
> I'd also note that adding visible methods at the constant level will
> only lead to requests to see each constant implement an interface,
> effectively creating class-style hierarchies within enum constants -
> what a mess that would be. (What would be more useful would be a
> backwards compatible migration path from enums to classes, so that the
> singleton nature and serialization safety is not lost).
>
> Stephen
>
>
> On 7 December 2016 at 10:36, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com> wrote:
>> For the records - here's a more complete example where lack of sharp typing
>> hurts, I think:
>>
>> http://hg.openjdk.java.net/valhalla/valhalla/langtools/file/ce7460995ffc/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Dynamic.java#l41
>>
>> The enum defines all possible kinds of constants which can appear as static
>> arguments in an invokedynamic call.
>>
>> As you can see, many of the methods in this enum are 'partial': they only
>> make sense for certain constants, but not for others. Currently, the only
>> way around this, is to declare this method at the root (the enum itself),
>> and then have the method throw some exception if it's not supposed to be
>> implemented for certain constants. I believe this idiom is a red herring;
>> you really don't want the asType/asSymbol be defined for a STRING constant -
>> and if they weren't, you would get more static type checking back which
>> would prevent you from calling methods that are not 'supported' rather than
>> relying to a runtime check.
>>
>> Maurizio
>>
>>
>>
>> On 07/12/16 09:48, Maurizio Cimadamore wrote:
>>> Thanks for the feedback. I personally run into the lack of sharp typing
>>> several times and seen other people stumbling on it too.
>>>
>>> Do you have some example in mind that will break - other than the ones
>>> listed in the JEP? In my mental model, the kind of surprises this introduces
>>> are very similar to anonymous inner class types - that is:
>>>
>>> new Object() { void m() { } }.m();
>>>
>>> this is legal code because the receiver expression doesn't have type
>>> Object - but has a sharper type (which can 'see' the additional member).
>>> This proposal is about doing the same with enums - which accidentally will
>>> sit well with adding generics (because in that case, the constants will have
>>> a richer generic type than their parent).
>>>
>>> Maurizio
>>>
>>>
>>> On 07/12/16 09:03, Remi Forax wrote:
>>>> Now, If this proposal is accepted, at least, instead of changing the spec
>>>> to introduce sharp types for all kind of enums, adding sharp type only for
>>>> generics enums,
>>>> it will break no code because generics enum currently do not compile.
>>>



More information about the platform-jep-discuss mailing list