我有KClass
到Int
的地图。然后我有一个具有固定泛型类型的函数。因此,我希望以下情况能够提供与Int
相关联的Boolean::class
val kclassToInt = mapOf(Boolean::class to 1, Byte::class to 1, Short::class to 2)
inline fun <reified T> myExpectations() =
assertEquals(1, kclassToInt.getRaw(T::class), "Why doesn't it work? :'(")
我通过Why doesn't it work? :'(. Expected <1>, actual <null>.
打电话给我myExpectations<Boolean>()
。
然后我尝试关闭.java
,所以我使用的是Java Class
而不是Kotlin的KClass
。
val classToInt = mapOf(Boolean::class.java to 1, Byte::class.java to 1, Short::class.java to 2)
inline fun <reified T : Any> anotherExpectation() =
assertEquals(1, classToInt.getRaw(T::class.java))
这次我再次受到断言错误的欢迎:java.lang.AssertionError: Expected <1>, actual <null>.
最后,我尝试使用.javaClass
而不是.java
:
val javaClassToInt = mapOf(Boolean::class.javaClass to 1, Byte::class.javaClass to 1, Short::class.javaClass to 2)
inline fun <reified T> pleaseWork() =
assertEquals(1, javaClassToInt.getRaw(T::class.javaClass))
这次真的很奇怪。我受到了欢迎:java.lang.AssertionError: Expected <1>, actual <2>.
这似乎是因为所有.javaClass
都引用了KClassImpl
。
最后我采取了我不想做的事情,使用.qualifiedName
:
val qnToInt = mapOf(Boolean::class.qualifiedName to 1, Byte::class.qualifiedName to 1, Short::class.qualifiedName to 2)
inline fun <reified T> iKnowItWorks() =
assertEquals(1, qnToInt.getRaw(T::class.qualifiedName))
当然有效,我在实际使用案例中使用的是:https://github.com/Jire/kotmem/blob/master/src/main/kotlin/org/jire/kotmem/Process.kt
答案 0 :(得分:3)
你很可能写过类似println(type.javaClass)
的内容似乎有意义,但实际上并不是因为它始终打印class kotlin.reflect.jvm.internal.KClassImpl
,因为这是内部实现类KClass
界面。
为什么type.javaClass
会这样运作? javaClass
是一个扩展属性,它获取作为接收者传递给它的任何值的运行时Java类。它的签名是:
val <T : Any> T.javaClass: Class<T>
type
是KClass<T>
类型的完全有效值,因此type.javaClass
的结果类型为Class<KClass<T>>
。除非您想要内省KClass
实现类的符号,否则这几乎完全没有意义。由于type
是运行时的KClassImpl
实例,type.javaClass
实际上是一个Class
实例,表示名为kotlin.reflect.jvm.internal.KClassImpl
的类。
这有点令人困惑,绝对不是你想要做的。如果要将类实例打印到屏幕,只需调用println(type)
即可。如果要获取与Class
实例对应的Java KClass
实例,可以使用java
扩展属性:type.java
。 java
的签名是:
val <T : Any> KClass<T>.java: Class<T>
因此,如果type
是KClass<T>
,那么type.java
就是Class<T>
。
答案 1 :(得分:1)
我相信Map中的键类型是基本类型的KClass
个实例(Java int而不是Integer)。函数中的具体类型是盒装类型(整数)的KClass
实例,如Are Kotlin's reified types incorrect for primitives on the JVM?中所示
虽然这两个KClass
打印的内容相同,但它们并不相同,因此您的查找失败。