MST
星途 面试题库

面试题:Kotlin泛型中的类型擦除问题

请阐述Kotlin泛型中类型擦除的概念,它会对泛型使用带来哪些影响?并举例说明如何在Kotlin代码中尽量避免因类型擦除导致的问题。
49.5万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试

类型擦除概念

在Kotlin泛型中,类型擦除指的是在编译阶段,所有的泛型类型信息都会被擦除,只保留原始类型。例如,List<String>在运行时实际类型是List<String>部分的类型信息在编译后不再保留。这是为了保证Java和Kotlin的兼容性,因为Java泛型同样存在类型擦除机制。

对泛型使用的影响

  1. 运行时无法获取真实类型:由于类型信息在运行时被擦除,无法通过常规方式获取泛型参数的实际类型。例如:
fun <T> printType(list: List<T>) {
    // 以下代码无法获取T的实际类型,classT始终为null
    val classT = list::class.java.typeParameters[0].typeBounds[0] 
    println(classT) 
}
  1. 无法创建泛型数组:因为运行时类型擦除,无法直接创建泛型数组。例如val array: Array<T> = Array(10) { T() }是不允许的,因为不知道T的具体类型。

避免因类型擦除导致问题的方法

  1. 使用reified类型参数(仅适用于内联函数)
    inline fun <reified T> getType() = T::class.java
    val stringClass = getType<String>()
    println(stringClass) 
    
    这里通过reified关键字,使得在运行时能够获取到实际的类型参数。
  2. 传递KClass对象
    fun <T> createInstance(kClass: KClass<T>): T {
        return kClass.java.newInstance()
    }
    val stringInstance = createInstance(String::class)
    
    通过显式传递KClass对象,在运行时提供必要的类型信息,从而避免类型擦除带来的问题。