Kotlin泛型类在MutableMap中存储时出现未检查转换警告问题
未检查转换警告的触发原因
你声明的泛型上界只能保证编译期调用的类型合法性,但是Kotlin的泛型是擦除实现的,运行时Binder实例不会携带VB和T的具体类型信息。你在put方法中执行的是普通as强转,编译器无法在编译期验证这个逆变泛型的转换是否真的安全,也无法在运行期做校验,所以会抛出未检查转换警告。reified关键字仅能帮你在inline函数内拿到泛型参数的Class对象,并不会消除泛型擦除对转换校验的影响,所以不会自动消除这类强转警告。
get方法无警告的原因
你在get方法中使用的是as?安全转换运算符,Kotlin编译器对安全转换的泛型强转默认不触发警告,因为你已经显式处理了转换失败为空的分支,编译器默认你自行承担转换风险,不管是否加inline和reified都不会触发警告。
无警告实现方案
最直接且合规的方案是显式压制你确认安全的未检查警告,这也是Kotlin生态中处理这类类型安全容器的通用实现,你只要保证put和get的类型匹配逻辑正确,压制警告不会带来运行时风险:
interface Binder<in VB: ViewBinding, in T: Any> { fun bind(binding: VB, item: T) } class TypeInfoMap { val map = mutableMapOf<Class<out Any>, Binder<ViewBinding, Any>>() @Suppress("UNCHECKED_CAST") inline fun <reified VB: ViewBinding, reified T: Any> put(binder: Binder<VB, T>) { map[T::class.java] = binder as Binder<ViewBinding, Any> } inline fun <reified VB: ViewBinding, reified T: Any> get(cls: Class<T>): Binder<VB, T> { return map[cls] as? Binder<VB, T> ?: throw IllegalStateException() } }
内容的提问来源于stack exchange,提问作者Cilenco
相关产品推荐
相关产品推荐

