我正在使用Kotlin编写适用于Java反射API的东西。我的输入是Class<*>
,我需要确定该类型是double还是整数,但我需要支持原语和 Java使用的盒装可空类型。
这个玩具示例正是我尝试做的事情:
when(type) {
java.lang.Double::class.java, Double::class.java -> TypesEnum.DOUBLE
java.lang.Integer::class.java, Int::class.java -> TypesEnum.INT
else -> throw IllegalArgumentException("type")
}
但是,这种方法会从Kotlin编译器生成以下警告:
警告:(22,13)Kotlin:这个课程不应该用在Kotlin中。请改用kotlin.Double。 警告:(23,13)Kotlin:这个课程不应该在Kotlin中使用。请改用kotlin.Int。
但是,Int?::class.java
是语法错误,the approaches suggested on an earlier question需要KClass
而不是Class<*>
(以及某些输入上的.kotlin
extension method崩溃) 。 Kotlin执行此类检查的正确方法是什么?
编辑:进一步调查(由@ voddan的回答提示)已经发现,这个问题是Kotlin类型反思中更为奇怪的一个症状:< / p>
fun main(args: Array<String>) {
// ::class.java of Kotlin's own Double type is just double
println(Double::class) // -> class kotlin.Double
println(Double::class.java) // -> double
// But starting from Java's nullable java.lang.Double gives an entirely different result
println(java.lang.Double::class) // -> class kotlin.Double
println(java.lang.Double::class.java) // -> class java.lang.Double
println(java.lang.Double::class.java.kotlin) // -> class kotlin.Double
println(java.lang.Double::class.java.kotlin.java) // -> class java.lang.Double
// Suggested by @mfulton26; works.
println(Class.forName("java.lang.Double")) // -> class java.lang.Double
}
所以似乎并非所有class kotlin.Double
都是平等的。我玩过演员表和辅助变量,结果看起来非常一致。
答案 0 :(得分:3)
Class.kotlin
应该有效。如果它在某些[你的]输入上崩溃了#34;然后我建议提交问题here。Class.forName(String)
。避免编译器警告。例如Class.forName("java.lang.Integer")
。您可以使用KClass.javaObjectType
和KClass.javaPrimitiveType
:
when (type) {
Double::class.javaObjectType, Double::class.javaPrimitiveType -> TypesEnum.DOUBLE
Int::class.javaObjectType, Int::class.javaPrimitiveType -> TypesEnum.INT
else -> throw IllegalArgumentException("type")
}
答案 1 :(得分:1)
Int?
不是类,而是类型,这意味着此类型的引用为以太int
,Integer
或null
。
Int::class.java
会给你java.lang.Integer
。
我目前无法检查,但IMO将Class
转换为KClass
是您的最佳选择:
when(type.kotlinClass) {
Double::class -> TypesEnum.DOUBLE
Int::class -> TypesEnum.INT
else -> throw IllegalArgumentException("type")
}