JEP 301: Enhanced Enums
Stephen Colebourne
scolebourne at joda.org
Wed Dec 7 11:19:52 UTC 2016
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