假设我们有以下内容:
val person = "Bill"
有人可以解释这两者之间的区别:
val kClass1 = person.javaClass.kotlin
VS
val kClass2 = person::class
什么时候应该打电话给那个而不是另一个?
任何源代码示例都将受到赞赏。
答案 0 :(得分:7)
有两种方法可以实现同样的事情,即得到一个对象的Kotlin类,是因为在Kotlin 1.1之前,::class
文字不支持左侧的表达式。因此,如果你正在使用Kotlin 1.0,那么你唯一的选择就是.javaClass.kotlin
,否则你对其中任何一个都没问题。这就是" Kotlin in Action"使用.javaClass.kotlin
语法:它是在Kotlin 1.1发布之前编写的。
这些表达的类型也存在细微差别。例如,在以下代码中
interface T
fun f1(x: T) = x::class
fun f2(x: T) = x.javaClass.kotlin
f1
的类型为KClass<out T>
,但f2
的类型为KClass<T>
。这实际上是javaClass
声明中的疏忽:KClass<out T>
在这种情况下更正确,因为x
的类不一定是T
,但也可以是T
的子类。
否则这两个表达式(x.javaClass.kotlin
和x::class
)在生成的字节码和运行时性能方面完全相同。我更喜欢x::class
,因为它更短,读起来更好。
答案 1 :(得分:0)
person.javaClass.kotlin
从Java类创建新的Kotlin类引用对象。所以只有你只有java类对象才有意义。
所以你应该使用person::class
,因为在这种情况下你只需直接获得Kotlin类而无需额外的对象分配
答案 2 :(得分:0)
没有人可以取代另一个,他们都有理由存在。
如果,您从KClass
的变量中获得null
,那么您更喜欢使用foo::class
,因为javaClass.kotlin
创建了每次都有新实例,例如:
assert(foo::class === foo::class);
assert(foo.javaClass.kotlin !== foo.javaClass.kotlin);
IF 您从可以为空的变量中获得KClass
,然后更喜欢使用如下所示:
val value:Int? = 1;
val type = value?.javaClass?.kotlin;
如果你从kotlin获得了一个java Class
,你希望转换为KClass
,然后使用Class.kotlin
,例如:
val javaClass:Class<Integer> = ...;
val kotlinClass:KClass<Integer> = javaClass.kotlin;