Inferring a generic type of Map in Kotlin

后端 未结 1 2344
攒了一身酷
攒了一身酷 2021-02-20 17:37

Consider a Java method which infers its type by Java class as follows:

public  T readJson(Class c) throws IOException {

This

相关标签:
1条回答
  • 2021-02-20 17:59

    Kotlin does not have anything like Java raw types (which were left in Java for backward compatibility), and the type system therefore does not allow this kind of unchecked assignment to be made implicitly (star projections, the closest concept to raw types in Kotlin, retain type safety).

    You can make an unchecked cast to Map<String, String>, thus expressing that you are aware of a possible type mismatch at runtime:

    @Suppress("UNCHECKED_CAST")
    val result = foo.readJson(Map::class.java) as Map<String, String>
    

    You can suppress the unchecked cast warning for a broader scope than just one statement.

    A natural improvement of this solution is writing a util function to hide the unchecked cast in it:

    @Suppress("UNCHECKED_CAST")
    inline fun <reified T: Any> JsonReader.readJson(): T {
        val result = readJson(T::class.java)
        return result as T
    }
    

    This solution uses an inline function with a reified type parameter: the function is transformed and substituted at each of its call sites, with T replaced by the specified (or inferred) type at compile time .

    Usage examples:

    val map = jsonReader.readJson<Map<String, String>>()
    

    fun processMap(map: Map<String, String) { /* ... */ }
    
    processMap(jsonReader.readJson()) // Map<String, String> is inferred for this call
    
    0 讨论(0)
提交回复
热议问题