如何将Class 与没有kotlin编译器警告的Java盒装原语types进行比较
我正在使用Kotlin编写一些与Java的reflectionAPI一起工作的东西。 我的输入是一个Class
,我需要决定这个types是double还是integer,但是我需要同时支持Java使用的原始types和可装箱的可空types。
这个玩具的例子做我想做的事情:
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的typesreflection更古怪的一个怪异的症状:
fun main(args: Array) { // ::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
s都是平等的。 我玩过演员和辅助variables,结果看起来非常一致。
-
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?
不是一个类,而是一个types,意味着这个types的引用是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") }