面试题答案
一键面试类型擦除概念
在Kotlin泛型中,类型擦除指的是在编译阶段,所有的泛型类型信息都会被擦除,只保留原始类型。例如,List<String>
在运行时实际类型是List
,<String>
部分的类型信息在编译后不再保留。这是为了保证Java和Kotlin的兼容性,因为Java泛型同样存在类型擦除机制。
对泛型使用的影响
- 运行时无法获取真实类型:由于类型信息在运行时被擦除,无法通过常规方式获取泛型参数的实际类型。例如:
fun <T> printType(list: List<T>) {
// 以下代码无法获取T的实际类型,classT始终为null
val classT = list::class.java.typeParameters[0].typeBounds[0]
println(classT)
}
- 无法创建泛型数组:因为运行时类型擦除,无法直接创建泛型数组。例如
val array: Array<T> = Array(10) { T() }
是不允许的,因为不知道T
的具体类型。
避免因类型擦除导致问题的方法
- 使用reified类型参数(仅适用于内联函数):
这里通过inline fun <reified T> getType() = T::class.java val stringClass = getType<String>() println(stringClass)
reified
关键字,使得在运行时能够获取到实际的类型参数。 - 传递
KClass
对象:
通过显式传递fun <T> createInstance(kClass: KClass<T>): T { return kClass.java.newInstance() } val stringInstance = createInstance(String::class)
KClass
对象,在运行时提供必要的类型信息,从而避免类型擦除带来的问题。