为何传入函数的Class<T>输出类型为String而非指定类型?
问题:统计列表特定类型元素时出现错误的类型输出
我尝试通过向函数传入数据类型来统计列表中特定类型元素的数量,但得到了错误的类型结果。以下是我的Kotlin代码:
fun <T> checkTypesOfElements(list: List<Any>, clazz: Class<T>): Unit { println(clazz.name::class.simpleName) // 预期打印要检查的类型 list.forEach { println(it::class.simpleName) } // 打印列表元素的类型 println(list.count { it::class == clazz.name::class }) // 统计匹配的元素数量 } fun main() { val listOfObjects = listOf(51, "Hello", 42, "Kotlin", 123L) checkTypesOfElements(listOfObjects, Long::class.java) }
输出结果如下:
String Int String Int String Long 2
为什么第一行输出的是String而不是Long?
原因分析与解决方法
第一行输出String的原因
你写的clazz.name::class.simpleName逻辑完全偏离了预期:
clazz是传入的Long::class.java,也就是Long的Java Class对象clazz.name会返回该Class的全名字符串,即"java.lang.Long"clazz.name::class是获取这个字符串对象的Kotlin类型,也就是String::class- 所以打印它的
simpleName自然是String,和你要检查的Long类型毫无关系
统计结果错误的原因
list.count { it::class == clazz.name::class }同样逻辑错误:
这里是拿列表元素的KClass(比如Int、String、Long)和String::class做比较,只有元素是String时才会匹配,列表里有两个字符串("Hello"和"Kotlin"),所以结果是2。
正确的写法
方法1:基于Java Class对象判断
直接使用Class对象的属性和比较逻辑:
fun <T> checkTypesOfElements(list: List<Any>, clazz: Class<T>): Unit { println(clazz.simpleName) // 直接打印Class的simpleName list.forEach { println(it::class.simpleName) } // 比较元素的Java类与传入的clazz是否一致 println(list.count { it.javaClass == clazz }) }
方法2:基于Kotlin KClass(更符合Kotlin风格)
直接传入KClass对象,避免Java与Kotlin类型体系的混淆:
import kotlin.reflect.KClass fun <T : Any> checkTypesOfElements(list: List<Any>, kClass: KClass<T>): Unit { println(kClass.simpleName) list.forEach { println(it::class.simpleName) } println(list.count { it::class == kClass }) } fun main() { val listOfObjects = listOf(51, "Hello", 42, "Kotlin", 123L) checkTypesOfElements(listOfObjects, Long::class) // 直接传入Long::class }
两种写法的输出都会符合预期:第一行打印Long,最后一行统计结果为1(列表里仅一个Long类型元素123L)。
内容的提问来源于stack exchange,提问作者Ацкий Конструктор
相关产品推荐
相关产品推荐

