Is there a way in Kotlin to create an empty EnumSe...
# announcements
d
Is there a way in Kotlin to create an empty EnumSet from a reflected enum Class? It seems like I can do it with Java, but not with Kotlin based on the enum type constraints and inference (and if I take Java code and paste it into Kotlin and have IntelliJ do the auto convert, it fails)
m
You can make use of generic type erasure, like this:
Copy code
import java.util.EnumSet
import kotlin.reflect.KClass


private enum class Dummy


@Suppress("UNCHECKED_CAST")
fun <E: Enum<E>> emptyEnumSet(clazz: KClass<E>) =
	EnumSet.noneOf(clazz.java as Class<Dummy>) as EnumSet<E>


@JvmName("emptyEnumSetOfUnspecificClass")
@Suppress("UNCHECKED_CAST")
fun emptyEnumSet(clazz: KClass<out Enum<*>>) =
	EnumSet.noneOf(clazz.java as Class<Dummy>) as EnumSet<*>


@Suppress("UNCHECKED_CAST")
inline fun <reified E: Enum<E>> emptyEnumSet() =
	EnumSet.noneOf(E::class.java as Class<Dummy>) as EnumSet<E>


enum class MyEnum {
	a,b
}


fun main() {
	val unspecificEnumClass = MyEnum::class as KClass<out Enum<*>>
	val emptySet1 = emptyEnumSet(MyEnum::class)
	val emptySet2 = emptyEnumSet<MyEnum>()
	val emptySet3 = emptyEnumSet(unspecificEnumClass)

	println(emptySet1)
	println(emptySet2)
	println(emptySet3)
}
d
Thanks. The above didn't exactly work for my needs (because I'm dealing with a Class<?> coming from Java so type inference still wasn't happy, but the idea to create an empty enum class and then cast to that does seem to work, which I hadn't thought of before.
m
You can use the method above, again with a little cast:
Copy code
val veryUnspecificClass: Class<*> = unspecificEnumClass.java
val emptySet4 = emptyEnumSet(veryUnspecificClass.kotlin as KClass<out Enum<*>>)
Class<?>
is quite unsafe, hence a cast needed.
Class<out Enum<*>>
would be better ๐Ÿ™‚
d
Yeah, I'm dealing with reflection, so I've already verified the class is an enum, so for my case it's safe
๐Ÿ‘ 1
If all I want is an an empty enum set instance, is there any reason I can't just declare the empty enum (Dummy in the above example) and then just do EnumSet.noneOf(Dummy::class.java)
m
You can, I just generalized your use-case with some functions and added different examples. But you have to cast the resulting
EnumSet<Dummy>
to
EnumSet<*>
๐Ÿ™‚
d
Cool. Yeah, in my case the value I'm assuming to is already Any?, so for me the cast isn't necessary
๐Ÿ‘ 1
In case anyone is wondering the use case here where everything seems so loosely typed, it's for our fork of the kotlin jackson module that allows us to automatically map null EnumSets to empty on deserialization (similarly, we have logic to map null lists/maps to empty lists/maps)
m
So could also be interesting for my own Kotlin JSON library ๐Ÿ˜„ I've never ever used
EnumSet
though ๐Ÿ˜ฎ Maybe I should add a Kotlin-version of it ๐Ÿ™‚
226 Views