[英]A reference to primitive type in Java (How to force a primitive data to remain boxed)
[英]How to compare a Class<*> against a Java boxed primitive type without kotlin compiler warnings
我正在使用Kotlin编写与Java的反射API一起使用的东西。 我的输入是Class<*>
,我需要确定该类型是双精度还是整数,但是我需要同时支持基元和 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
是语法错误, 在前面的问题中建议的方法需要KClass
而不是Class<*>
(并且.kotlin
扩展方法在我的某些输入上崩溃)。 Kotlin执行这种检查的正确方法是什么?
编辑:进一步的调查(由@voddan的回答提示)表明,此问题是Kotlin的类型反射中更普遍的怪异现象的征兆:
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
都被创建为相等的。 我玩过强制转换和辅助变量,结果似乎高度一致。
Class.kotlin
应该可以工作。 如果它“破坏了您的某些输入”,那么我建议在此处提出问题。 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") }
Int?
不是类,而是类型,表示此类型的引用是ether 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")
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.