Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin - when expression over class type

Tags:

kotlin

I'm attempting to write an invocation handler that uses a map (supplied at runtime) to implement an interface's getters.

This very crudely works. I know the basic types that may be returned, so I'm OK with having a when expression.

I haven't found a way to avoid using the name of the class as the subject of the when expression; is there a better way?

class DynamicInvocationHandler<T>(private val delegate: Map<String, Any>, clzz: Class<T>) : InvocationHandler {

    val introspector = Introspector.getBeanInfo(clzz)
    val getters = introspector.propertyDescriptors.map { it.readMethod }

    override fun invoke(proxy: Any, method: Method, args: Array<Any>?): Any? {
        if (method in getters) {
            // get the value from the map
            val representation = delegate[method.name.substring(3).toLowerCase()]
            // TODO need better than name
            when (method.returnType.kotlin.simpleName) {                
                LocalDate::class.simpleName -> {
                    val result = representation as ArrayList<Int>
                    return LocalDate.of(result[0], result[1], result[2])
                }
                // TODO a few other basic types like LocalDateTime
                // primitives come as they are
                else -> return representation
            }
        }
        return null
    }
}
like image 355
fridgepolice Avatar asked Oct 21 '25 04:10

fridgepolice


2 Answers

You can use the types instead of the class names in the when statement. After a type is matched, Kotlin smart cast will automatically cast it

Example

val temporal: Any? = LocalDateTime.now()

when (temporal){
    is LocalDate -> println("dayOfMonth: ${temporal.dayOfMonth}")
    is LocalTime -> println("second: ${temporal.second}")
    is LocalDateTime -> println("dayOfMonth: ${temporal.dayOfMonth}, second: ${temporal.second}")
}
like image 105
Omar Mainegra Avatar answered Oct 23 '25 09:10

Omar Mainegra


when expressions support any type (unlike Java's switch), so you can just use the KClass instance itself:

when (method.returnType.kotlin) {                
    LocalDate::class -> {
        ...
    }
    ...
}
like image 22
Salem Avatar answered Oct 23 '25 10:10

Salem