Kotlin中T::class.java为何是Class<out Int>?如何获取泛型T的Class?
问题原因与解决方案
首先得说你代码里有两个关键问题导致typeClass变成了Int而不是你期望的T类型:
1. 错误的类型限定
你把typeClass的类型硬写成了Class<out Int>,这相当于强制这个属性只能是Int或者它的子类的Class对象,不管你指定的泛型T是什么,编译器都会把T::class.java往Class<out Int>上转,这自然就会导致用User的时候出问题——因为User和Int没关系,编译器只能默认给你Int的Class了。
2. 泛型擦除的限制
Kotlin的泛型在运行时会被擦除,普通泛型类里直接写T::class.java是拿不到实际的T的Class对象的,因为编译后JVM不知道T具体是什么类型。
解决办法有两种,看你哪种更顺手:
办法一:显式传入Class
直接把typeClass的类型改成Class<T>,并且去掉错误的默认类型限定,使用的时候手动传入目标类的Class:
// 修改后的类定义 class ResponseHandler<T : Any>( val typeClass: Class<T>, val start: () -> Unit = {}, val success: (result: SuccessInfo<T>) -> Unit, val complete: () -> Unit = {} ) { /*...*/ } // 使用示例 ResponseHandler(User::class.java, success = { userInfo -> // 处理User类型的成功结果 })
办法二:用inline+reified泛型简化调用
如果你不想每次都手动传Class,可以写一个inline的工厂函数,利用reified泛型保留T的类型信息:
// 先保留修改后的类定义(typeClass为Class<T>) class ResponseHandler<T : Any>( val typeClass: Class<T>, val start: () -> Unit = {}, val success: (result: SuccessInfo<T>) -> Unit, val complete: () -> Unit = {} ) { /*...*/ } // 定义inline工厂函数 inline fun <reified T : Any> ResponseHandler( noinline start: () -> Unit = {}, noinline success: (result: SuccessInfo<T>) -> Unit, noinline complete: () -> Unit = {} ): ResponseHandler<T> { return ResponseHandler(T::class.java, start, success, complete) } // 使用的时候就不用传Class了,直接指定泛型参数 ResponseHandler<User>(success = { userInfo -> // 处理User类型的成功结果 })
这样修改后,ResponseHandler<User>(...)的typeClass就会是User::class.java,完全符合你的需求啦。
内容的提问来源于stack exchange,提问作者bigxinwen
相关产品推荐
相关产品推荐

