【问题标题】:How to compare a Class<*> against a Java boxed primitive type without kotlin compiler warnings如何在没有 kotlin 编译器警告的情况下将 Class<*> 与 Java 盒装原始类型进行比较
【发布时间】:2016-12-16 03:09:40
【问题描述】:

我正在使用 Kotlin 编写与 Java 反射 API 配合使用的东西。我的输入是Class&lt;*&gt;,我需要确定该类型是双精度型还是整数型,但我需要同时支持原语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&lt;*&gt;(并且 .kotlin extension method 在我的某些输入上崩溃)。执行这种检查的正确 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.Doubles 都是平等的。我玩过演员表和辅助变量,结果似乎非常一致。

【问题讨论】:

    标签: java reflection kotlin


    【解决方案1】:
    1. Class.kotlin 应该可以工作。如果它“在某些 [你的] 输入上崩溃”,那么我建议提交一个问题 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")
      }
      

    【讨论】:

    • Class.kotlin 适用于 try.kotlinlang.org 但不适用于我的系统,所以这显然是正确的答案,但我的环境一团糟。
    • Class.forName("java.lang.Double").kotlin 在 when 块中匹配 Double::class,但仅在 kotlin 1.0.4 及更高版本上。我有一个旧版本。
    【解决方案2】:

    Int? 不是一个类,而是一个类型,这意味着该类型的引用是 ether 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")
    }
    

    【讨论】:

    • Int::class.java 只是 int,而不是 java.lang.Integer。通过更多实验编辑问题。
    • 是的,但是无论原始类型是什么,type.kotlin 都应该返回 Int
    猜你喜欢
    • 1970-01-01
    • 2019-06-24
    • 2015-09-24
    • 2022-07-20
    • 1970-01-01
    • 2019-05-28
    • 1970-01-01
    • 2011-04-30
    • 2012-07-18
    相关资源
    最近更新 更多