由於type erasure,實際泛型參數不能通過通用類的T::class
標記獲得。類的不同對象必須具有相同的類標記,這就是爲什麼它不能包含實際的泛型參數。
但是有一個叫做super type tokens的技巧,它可以在編譯時知道類型的實際類型參數(因爲內聯對Kotlin中的泛化泛型是真的)。
訣竅是編譯器保留了從泛型類派生的非泛型類的實際類型參數(它的所有實例都有相同的參數,很好的解釋here)。他們可以通過實例的clazz.genericSuperClass.actualTypeArguments
訪問。
鑑於這一切,你可以寫一個實用程序類是這樣的:
abstract class TypeReference<T> : Comparable<TypeReference<T>> {
val type: Type =
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
override fun compareTo(other: TypeReference<T>) = 0
}
解釋Jackson TypeReference它使用相同的方法。傑克遜Kotlin模塊uses it關於泛化的泛型。
之後,在與通用的具體化,需要一個TypeReference
被子類的內聯函數(一個object expression會去),然後將其type
可以使用。
實施例:
inline fun <reified T: Any> printGenerics() {
val type = object : TypeReference<T>() {}.type
if (type is ParameterizedType)
type.actualTypeArguments.forEach { println(it.typeName) }
}
printGenerics<HashMap<Int, List<String>>>()
:
java.lang.Integer
java.util.List<? extends java.lang.String>
更換** **任何與所需的接口,並與工作接口:) –