Kotlin:如何检查一个类是否为对象类?

3
我有一个 Kotlin 对象和一个 Java 类,如下所示:

KotlinObject.kt

object KotlinObject{
....
}

JavaClass.java

class JavaClass {
...
}

并且有一个用于检查的 Kotlin 函数:

fun foo(cls: Class<*>): Any {
   if (cls is kotlin's object) { //how to do this?
      return ?  //wanna return object's instance
   } else {
      return cls.newInstance()
   }    
}

我可以把 Kotlin 对象或 Java 类传递给这个函数:
foo(KotlinObject::class.java)
foo(JavaClass::class.java)

那么有可能确定哪一个是 Kotlin 的对象吗?


你必须传递每个对象的Java版本吗?你能传递KotlinObject :: class和JavaClass :: class吗?甚至可以传递类型本身。我只是有一种感觉,一旦你做了'.java'的事情,你就剥夺了与每个“对象”相关联的许多元数据。 - CryptoFool
1
你“假设”它是一个对象类的唯一方法,就是检查它是否有一个静态的INSTANCE字段,但这并不能给你100%的确定答案。如果你在一个普通的Java类中添加一个静态字段INSTANCE,你会得到一个错误的结果。 尽管如此,这听起来非常可疑...你能分享一些更多关于为什么你需要它的细节吗?我有一种感觉你在过度思考某些事情。 - Bartek Lipinski
只是好奇,知道某个东西是对象还是类有什么意义吗? - noiaverbale
@Steve:“我只是有一种感觉,一旦你做了'.java'的事情,你就剥夺了与每个“对象”相关联的许多元数据。”不,有一种方法可以将其转换回KClass.kotlin扩展属性。 - Alexey Romanov
@AlexeyRomanov - 啊,好的,知道了! - CryptoFool
2个回答

6

感谢 @Alexey Romanov 在评论中指出 Kotlin 类信息可以从 Class<*> 中获取。

fun foo(cls: Class<*>) {
    if (cls.kotlin.objectInstance != null)
        println("KotlinObject")
    else
        println("Other class")
}

我的原始方法是模仿 Kotlin 的 KClass.objectInstance

我将其保留供参考,但请使用上面提供的解决方案。

fun foo(cls: Class<*>) {
    val objectInstance = cls.declaredFields.firstOrNull {
        it.type == cls && it.name == "INSTANCE"
    }

    if (objectInstance != null)
        println("KotlinObject")
    else
        println("Other class")
}

需要注意的是,使用名称“INSTANCE”作为单例字段的任何Java Singleton在这种情况下也将被报告为Kotlin对象。


我认为这不是OP想要的。他不想知道何时拥有JavaClass或KotlinObject的实例。相反,我认为他想知道任意类型是类类型还是对象类型。无论如何,这就是我的理解方式。换句话说,“foo”需要在不知道JavaClass和KotlinObject存在的情况下工作。 - CryptoFool
好的,所以示例必须是foo(KotlinObject())和foo(JavaClass())。 - Alexander Egger
问题已经更新,希望更加清晰明了。 - Ted
我也是!简短回答……在Java文件中定义JavaClass很好,仍然有效。 - CryptoFool
好的!我不知道那个。我已经更新了我的答案。 - Alexander Egger
显示剩余3条评论

2
最初的回答。
收到!
object KotlinObject{}
class JavaClass {}

fun foo(cls: KClass<*>) {
    if (cls.objectInstance != null)
        println("It's a Kotlin object")
    else
        println("It's NOT a Kotlin object")
}

fun main(args: Array<String>) {
    foo(KotlinObject::class)
    foo(JavaClass::class)
}

输出:

It's a Kotlin object
It's NOT a Kotlin object

如果出于某种原因必须传递Java类,则我无法找到任何方法来实现此操作。我认为所有的区别都不存在了。
注意:即使JavaClass在Java文件中定义,这也可以工作。在Kotlin中,每个对象都是KClass类型,无论它是在何处以何种方式定义的。也就是说,::class适用于Kotlin中的任何对象。

实际上,JavaClass是一个Java类,因此我认为我们无法将Java类作为KClass传递。我更新了我的问题以使其更清晰。 - Ted
即使JavaClass在Java中定义,这对我来说也很好用。在Kotlin中<object>::class始终是一个KClass。如果不是这样,您就无法添加“.java”,因为这是在KClass中定义的构造。 - CryptoFool

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接