Type parameters for enum constructor


#1

I cannot port the following Java code to Kotlin because it prohibits type parameters for enum constructors

enum Numbers {

    ...

    ;

    <N extends Number> Numbers(Factory<N> factoryA, Factory<N> factoryB) {

    }
}

Is there a workaround for this?


#2

Maybe you can use sealed classes: https://kotlinlang.org/docs/reference/sealed-classes.html

In your case maybe something like this? You can move the constructor of One to Numbers for general cases.

sealed class Numbers {
    class One<out N: Numbers>(val factoryA: Factory<N>, val factoryB: Factory<N>) : Numbers()
}

#3

It is not acceptable if you should support legacy Java code as well. I cannot just remove the existing enumeration and replace it with a class hierarchy. It is too expensive in my case.


#4

Unfortunately I guess this is one of Kotlin’s current shortcomings, you asked for a workaround and here it is. Sealed classes are extensions of Enums and should work mostly the same, so I don’t think you are losing too much over there. I’m not a kotlin expert so I maybe wrong.


#5

The only workaround I can think of is to use a generic factory method:

enum class Numbers {
    ...

    ;
 
   companion object {
       fun <N : Number> create(factoryA: Factory<N>, factoryB: Factory<N>): Numbers {
           // return something
       }
   }
} 

You can then call it with somethig like this:

val n = Numbers.create(factoryA, factoryB)

#6

Unfortunately, a factory-method work-around will not work with enum classe and Kotlin indeed does not support type parameters for constructors. Here is a relevant issue: https://youtrack.jetbrains.com/issue/KT-18741


#7

Thanks!