Reputation: 1881
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.
Upvotes: 6
Views: 5920
Reputation: 32816
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
interface T
fun f1(x: T) = x::class
fun f2(x: T) = x.javaClass.kotlin
f1
's type is KClass<out T>
, but f2
's type is KClass<T>
. This is actually an oversight in the javaClass
declaration: KClass<out T>
is more correct in this case, because x
's class is not necessarily T
, but can also be a subclass of T
.
Otherwise these two expressions (x.javaClass.kotlin
and x::class
) are completely equivalent in terms of produced bytecode and runtime performance. I prefer x::class
because it's shorter and reads better.
Upvotes: 8
Reputation: 30696
No one can replace another one, They both have reason to exist.
IF you get a KClass
from a variable that can't be null
then you prefer to using foo::class
since javaClass.kotlin
create a new instance each time, for example:
assert(foo::class === foo::class);
assert(foo.javaClass.kotlin !== foo.javaClass.kotlin);
IF you get a KClass
from a nullable variable then prefer to using as below:
val value:Int? = 1;
val type = value?.javaClass?.kotlin;
IF you get a java Class
from kotlin you want to transform to KClass
then using Class.kotlin
for example:
val javaClass:Class<Integer> = ...;
val kotlinClass:KClass<Integer> = javaClass.kotlin;
Upvotes: 0
Reputation: 1894
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
Upvotes: 0