The difference in these two constructs is that for the expression foo static (declared or supposed) type foo :
In fact, the latter is more accurate, because the actual value that foo evaluates may not be an instance of foo itself, but one of its subtypes (and this is exactly what is denoted by the covariant out Foo ).
As @marstran correctly noted in the commentary on the question, .javaClass once considered deprecated (see Kotlin 1.1 RC declaration ), since it could violate type safety (see below), but later it remained as it is because it was widely used and replaced it with an alternative ::class.java , would require the addition of explicit unchecked throws to the code.
Also see comments on this answer: (link)
Note that Int.javaClass does not denote an Int type, but instead is a Java class of an Int companion object. While Int::class.java is a reference to an unrelated class and denotes a type. To get it using .javaClass , you need to call it on an Int instance, for example. 1.javaClass .
This is how .javaClass can violate type safety. This code compiles but breaks at runtime:
open class Foo class Bar : Foo() { val baz: Int = 0 } fun main(args: Array<String>) { val someFoo: Foo = Bar() val anotherFoo: Foo = Foo() val someFooProperty: KProperty1<in Foo, *> = // 'in Foo' is bad someFoo.javaClass.kotlin.memberProperties.first() val someValue = someFooProperty.get(anotherFoo) }
This example uses kotlin-reflect .
This is because someFooProperty represents the Bar property, not foo , but since it was obtained from someFoo.javaClass ( Class<Foo> and then converted to KClass<Foo> ), the compiler allows us to use it with an in Foo projection.
hotkey
source share