General casting in Kotlin

I am trying to do mapOf () returns EnumMap if K is Enum. However, an error occurs with a variable of the first type Enum (K)

the code:

@kotlin.internal.InlineOnly
public inline fun <reified K, V> mapOf(): Map<K, V> =
    if (K::class.java.isEnum) EnumMap<K, V>(K::class.java)
    else emptyMap()

Error:

Type argument is not within its bounds.
Expected: Enum<K!>!
Found: K

I would like to provide objects other than Enum, so reified K: Enum<*>it cannot be a solution.

+4
source share
2 answers

Evil deception using erase styles:

import java.util.concurrent.TimeUnit // you can use any other enum as well

@Suppress("UNCHECKED_CAST")
public inline fun <reified K, V> mapOf(): Map<K, V> =
    if (K::class.java.isEnum) 
        EnumMap<TimeUnit, V>(K::class.java as Class<TimeUnit>) as Map<K, V>
    else emptyMap()

At runtime, it’s actually simple EnumMap(K::class.java), all casts disappear.

+3
source

(afaik), K K extends Enum<K> ( EnumMap) K, , generics - .

java EnumMap (.. , ). , . , :

val constructor = EnumMap::class.constructors.find {
    con ->
        con.parameters.size == 1
        && con.parameters[0].type.jvmErasure == Class::class
}!!

inline fun <reified K, V> mapOf(): Map<K, V> =
    if (K::class.java.isEnum) constructor.call(K::class.java) as Map<K, V>
    else emptyMap()

, . .

+2

Source: https://habr.com/ru/post/1696107/


All Articles