Add EnumMap.keyType() and EnumSet.elementType()

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Add EnumMap.keyType() and EnumSet.elementType()

Andrej Golovnin-2
Hi all,

it would be nice if we would have access to the class of the enum type
used to create an EnumMap or an EnumSet.

This is usefull when you write a custom serialization library and
would like to serialize/deserialize an empty EnumMap or an empty
EnumSet. For the empty EnumSet there is a workaround to get the enum
class:

EnumSet<MyEnum> empty = EnumSet.noneOf(MyEnum.class);
EnumSet<MyEnum> tmp = EnumSet.complementOf(empty);
Class<?> elementType = tmp.iterator().next().getClass();

But this only works when the enum class has at least one enum. For
EnumMap there is no such workaround at all and we have to use the
Reflection API. And you know the warnings since Java 9 :-) :

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by c.r.r.k.EnumMapSerializer to
field java.util.EnumMap.keyType
WARNING: Please consider reporting this to the maintainers of
c.r.r.k.EnumMapSerializer
WARNING: Use --illegal-access=warn to enable warnings of further
illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

So to avoid this warning and to avoid that our application stops to
work with a future release of Java I would like to propose to add the
following two methods:

EnumMap:
    /**
     * Returns the {@code Class} object of the key type for this enum map.
     *
     * @return the {@code Class} object of the key type for this enum map.
     *
     * @since 10
     */
    public Class<K> keyType()


EnumSet:
    /**
     * Returns the {@code Class} object of all the elements of this set.
     *
     * @return the {@code Class} object of all the elements of this set.
     *
     * @since 10
     */
    public Class<E> elementType()

The suggested change is attached as diff.

Best reagrds,
Andrej Golovnin

EnumMap_EnumSet.diff (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Add EnumMap.keyType() and EnumSet.elementType()

Stephen Colebourne-2
I'm surprised I've never run into this. This seems like a simple and
useful change.
Stephen

On 7 December 2017 at 11:40, Andrej Golovnin <[hidden email]> wrote:

> Hi all,
>
> it would be nice if we would have access to the class of the enum type
> used to create an EnumMap or an EnumSet.
>
> This is usefull when you write a custom serialization library and
> would like to serialize/deserialize an empty EnumMap or an empty
> EnumSet. For the empty EnumSet there is a workaround to get the enum
> class:
>
> EnumSet<MyEnum> empty = EnumSet.noneOf(MyEnum.class);
> EnumSet<MyEnum> tmp = EnumSet.complementOf(empty);
> Class<?> elementType = tmp.iterator().next().getClass();
>
> But this only works when the enum class has at least one enum. For
> EnumMap there is no such workaround at all and we have to use the
> Reflection API. And you know the warnings since Java 9 :-) :
>
> WARNING: An illegal reflective access operation has occurred
> WARNING: Illegal reflective access by c.r.r.k.EnumMapSerializer to
> field java.util.EnumMap.keyType
> WARNING: Please consider reporting this to the maintainers of
> c.r.r.k.EnumMapSerializer
> WARNING: Use --illegal-access=warn to enable warnings of further
> illegal reflective access operations
> WARNING: All illegal access operations will be denied in a future release
>
> So to avoid this warning and to avoid that our application stops to
> work with a future release of Java I would like to propose to add the
> following two methods:
>
> EnumMap:
>     /**
>      * Returns the {@code Class} object of the key type for this enum map.
>      *
>      * @return the {@code Class} object of the key type for this enum map.
>      *
>      * @since 10
>      */
>     public Class<K> keyType()
>
>
> EnumSet:
>     /**
>      * Returns the {@code Class} object of all the elements of this set.
>      *
>      * @return the {@code Class} object of all the elements of this set.
>      *
>      * @since 10
>      */
>     public Class<E> elementType()
>
> The suggested change is attached as diff.
>
> Best reagrds,
> Andrej Golovnin
Reply | Threaded
Open this post in threaded view
|

Re: Add EnumMap.keyType() and EnumSet.elementType()

Remi Forax
Hi Andrej,
I do not think it's a good idea.

It's like exposing reified type arguments, i can see these kind of change back firing in at least two ways.
It's not future proof, part of valhalla requires to change generics to allow generics of value types which requires a form of reification, but we may end up with a light form of reification similar to Scala type manifest (type arguments are available at construction time but not after that point) exposing type arguments for EnumSet will be seen as a mismatch in that case. Also, we may want to introduce unmodifiable EnumSet in the future, currently an unmodifiable empty EnumSet do not need to store any type argument, the proposed API force us to have as many empty EnumSet as type arguments combination (it's why you have one static field by type specialization in C#), again it makes the proposed API not future proof.

regards,
Rémi

----- Mail original -----
> De: "Stephen Colebourne" <[hidden email]>
> À: "core-libs-dev" <[hidden email]>
> Envoyé: Jeudi 7 Décembre 2017 13:09:40
> Objet: Re: Add EnumMap.keyType() and EnumSet.elementType()

> I'm surprised I've never run into this. This seems like a simple and
> useful change.
> Stephen
>
> On 7 December 2017 at 11:40, Andrej Golovnin <[hidden email]> wrote:
>> Hi all,
>>
>> it would be nice if we would have access to the class of the enum type
>> used to create an EnumMap or an EnumSet.
>>
>> This is usefull when you write a custom serialization library and
>> would like to serialize/deserialize an empty EnumMap or an empty
>> EnumSet. For the empty EnumSet there is a workaround to get the enum
>> class:
>>
>> EnumSet<MyEnum> empty = EnumSet.noneOf(MyEnum.class);
>> EnumSet<MyEnum> tmp = EnumSet.complementOf(empty);
>> Class<?> elementType = tmp.iterator().next().getClass();
>>
>> But this only works when the enum class has at least one enum. For
>> EnumMap there is no such workaround at all and we have to use the
>> Reflection API. And you know the warnings since Java 9 :-) :
>>
>> WARNING: An illegal reflective access operation has occurred
>> WARNING: Illegal reflective access by c.r.r.k.EnumMapSerializer to
>> field java.util.EnumMap.keyType
>> WARNING: Please consider reporting this to the maintainers of
>> c.r.r.k.EnumMapSerializer
>> WARNING: Use --illegal-access=warn to enable warnings of further
>> illegal reflective access operations
>> WARNING: All illegal access operations will be denied in a future release
>>
>> So to avoid this warning and to avoid that our application stops to
>> work with a future release of Java I would like to propose to add the
>> following two methods:
>>
>> EnumMap:
>>     /**
>>      * Returns the {@code Class} object of the key type for this enum map.
>>      *
>>      * @return the {@code Class} object of the key type for this enum map.
>>      *
>>      * @since 10
>>      */
>>     public Class<K> keyType()
>>
>>
>> EnumSet:
>>     /**
>>      * Returns the {@code Class} object of all the elements of this set.
>>      *
>>      * @return the {@code Class} object of all the elements of this set.
>>      *
>>      * @since 10
>>      */
>>     public Class<E> elementType()
>>
>> The suggested change is attached as diff.
>>
>> Best reagrds,
> > Andrej Golovnin
Reply | Threaded
Open this post in threaded view
|

Re: Add EnumMap.keyType() and EnumSet.elementType()

Andrej Golovnin-2
Hi Rémi,

> It's like exposing reified type arguments, i can see these kind of change back firing in at least two ways.
> It's not future proof, part of valhalla requires to change generics to allow generics of value types which requires a form of reification, but we may end up with a light form of reification similar to Scala type manifest (type arguments are available at construction time but not after that point) exposing type arguments for EnumSet will be seen as a mismatch in that case. Also, we may want to introduce unmodifiable EnumSet in the future, currently an unmodifiable empty EnumSet do not need to store any type argument, the proposed API force us to have as many empty EnumSet as type arguments combination (it's why you have one static field by type specialization in C#), again it makes the proposed API not future proof.

Only the death is future proof. Everything else is debatable. (c) :-P
Empty EnumSet is not a problem. As I already said there is a workaround
(an ugly one, but it is there). The real problem is an empty EnumMap.
When the valhalla project would provide a solution to my problem, then
I’m fine with it. When not, then let us debate about an alternative solution. :-)

Best regards,
Andrej Golovnin