如何比较Class< *>针对没有kotlin编译器警告的Java盒装基元类型

时间:2016-12-16 03:09:41

标签: java reflection kotlin

我正在使用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都是平等的。我玩过演员表和辅助变量,结果看起来非常一致。

2 个答案:

答案 0 :(得分:3)

  1. Class.kotlin应该有效。如果它在某些[你的]输入上崩溃了#34;然后我建议提交问题here
  2. 您可以使用Class.forName(String)。避免编译器警告。例如Class.forName("java.lang.Integer")
  3. 您可以suppress发出警告。
  4. 您可以使用KClass.javaObjectTypeKClass.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?不是类,而是类型,这意味着此类型的引用为以太intIntegernull

我认为

Int::class.java会给你java.lang.Integer

我目前无法检查,但IMO将Class转换为KClass是您的最佳选择:

when(type.kotlinClass) {
    Double::class -> TypesEnum.DOUBLE
    Int::class   -> TypesEnum.INT
    else -> throw IllegalArgumentException("type")
}