#android #generics #kotlin #interface #fragment
#Android #универсальные #kotlin #интерфейс #фрагмент
Вопрос:
Как получить тип универсального класса и привести к нему объект?
Я хочу использовать эту функцию для передачи класса интерфейса:
protected fun <T> getInteraction(): T {
return when {
context is T -> context
parentFragment is T -> parentFragment as T
else -> throw IllegalArgumentException("not implemented interaction")
}
}
и использовать его как:
private var interaction: ISigninInteraction? = null
override fun onAttach(context: Context?) {
super.onAttach(context)
interaction = getInteraction<ISigninInteraction>()
}
Ответ №1:
В Kotlin, Java и JVM типы стираются при реализации обобщений. Универсальные объекты не видны на уровне байт-кода. Это означает, что вы не можете использовать параметры типа, например T
, непосредственно в коде функции.
Kotlin добавляет поддержку reified
дженериков, которая помогает здесь. Вы можете объявить функцию следующим образом
inline fun <reified T> getIt() : T {
...
}
С помощью reified
и inline
можно будет привести к T
и вернуть его.
https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters
Вторая альтернатива — следовать практике Java — добавить Class<T>
параметр в функцию и использовать Class#cast
для приведения к T
вместо этого.
Вы можете объединить reified inline
функцию с подходом, подобным:
inline fun <reified T> getIt() = getIt(T::class.java)