How to get generic parameter class in Kotlin

后端 未结 5 799
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-05 09:30

Firebase\'s snapshot.getValue() expects to be called as follows:

snapshot?.getValue(Person::class.java)

However I would like t

5条回答
  •  无人及你
    2020-12-05 09:56

    For a class with generic parameter T, you cannot do this because you have no type information for T since the JVM erases the type information. Therefore code like this cannot work:

    class Storage {
        val snapshot: Snapshot? = ...
    
        fun retrieveSomething(): T? {
            return snapshot?.getValue(T::class.java) // ERROR "only classes can be used..."
        }
    }
    

    But, you can make this work if the type of T is reified and used within an inline function:

    class Storage {
        val snapshot: Snapshot? = ...
    
        inline fun  retrieveSomething(): T? {
            return snapshot?.getValue(T::class.java)
        }
    }
    

    Note that the inline function if public can only access public members of the class. But you can have two variants of the function, one that receives a class parameter which is not inline and accesses private internals, and another inline helper function that does the reification from the inferred type parameter:

    class Storage {
        private val snapshot: Snapshot? = ...
    
        fun  retrieveSomething(ofClass: Class): T? {
            return snapshot?.getValue(ofClass)
        }
    
        inline fun  retrieveSomething(): T? {
            return retrieveSomething(T::class.java)
        }
    }
    

    You can also use KClass instead of Class so that callers that are Kotlin-only can just use MyClass::class instead of MyClass::class.java

    If you want the class to cooperate with the inline method on the generics (meaning that class Storage only stores objects of type T):

    class Storage  {
        val snapshot: Snapshot? = ...
    
        inline fun  retrieveSomething(): R? {
            return snapshot?.getValue(R::class.java)
        }
    }
    

    The link to reified types in inline functions: https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters

提交回复
热议问题