Let's say that we have the following:
val person = "Bill"
Could someone explain the difference between these two:
val kClass1 = person.javaClass.kotlin
vs
val kClass2 = person::class
When I should call the one instead of the other?
Any source code example would be appreciated.
No one can replace another one, They both have reason to exist.
IF you get a
KClass
from a variable that can't benull
then you prefer to usingfoo::class
sincejavaClass.kotlin
create a new instance each time, for example:IF you get a
KClass
from a nullable variable then prefer to using as below:IF you get a java
Class
from kotlin you want to transform toKClass
then usingClass.kotlin
for example:The main reason there are two ways to achieve the same thing, namely get the Kotlin class of an object, is because prior to Kotlin 1.1, the
::class
literal did not support the expression on its left-hand side. So if you're using Kotlin 1.0, your only option is.javaClass.kotlin
, otherwise you're fine with either of them. This is the reason "Kotlin in Action" uses the.javaClass.kotlin
syntax: it was written before the Kotlin 1.1 release.There's also a minor difference in the types of these expressions. For example, in the following code
f1
's type isKClass<out T>
, butf2
's type isKClass<T>
. This is actually an oversight in thejavaClass
declaration:KClass<out T>
is more correct in this case, becausex
's class is not necessarilyT
, but can also be a subclass ofT
.Otherwise these two expressions (
x.javaClass.kotlin
andx::class
) are completely equivalent in terms of produced bytecode and runtime performance. I preferx::class
because it's shorter and reads better.person.javaClass.kotlin
creates new Kotlin class reference object from Java class. So it makes sense only if you have only java class object.So you should use
person::class
because in this case you just get Kotlin class directly without additional objects allocation