To initialize my logger apparently I need:
val LOGGER : Logger = LoggerFactory.getLogger(Foo::class.java);
If I do:
val LOGGER : Logger = LoggerFactory.getLogger(Foo::javaClass);
It complains that the parameter type is not compatible with getLogger
. However according to the API, both are Class<Foo>
. How are they different?
The Class class is a part of the Java API for the purposes of reflection. Whereas the class keyword is a structure of the Java language marking the definition of a new class, the Class class is used to type variables and parameters as classes themselves.
What Does Class Mean? A class — in the context of Java — is a template used to create objects and to define object data types and methods. Classes are categories, and objects are items within each category. All class objects should have the basic class properties.
The javaClass
is an extension property that returns the runtime Java class of an instantiated object. In your case, it is being used as a property reference, which will give you a KProperty1<Foo, Class<Foo>>
representing the extension function itself:
val T.javaClass: java.lang.Class<T>
You could use this in combination with a receiver, e.g. if Foo
provided a default constructor you could say:
Foo::javaClass.get(Foo())
which may be simplified to:
Foo().javaClass
Using ::class.java
on the other hand, gives you the Java Class<?>
as described in "class references" directly. All three possibilities in a simple example:
val kProperty1: KProperty1<Foo, Class<Foo>> = Foo::javaClass
kProperty1.get(Foo()) //class de.swirtz.kotlin.misc.Foo
Foo::class.java //class de.swirtz.kotlin.misc.Foo
Foo().javaClass //class de.swirtz.kotlin.misc.Foo
javaClass
is an extension property which returns the runtime Java class of an object.
/**
* Returns the runtime Java class of this object.
*/
public inline val <T: Any> T.javaClass : Class<T>
@Suppress("UsePropertyAccessSyntax")
get() = (this as java.lang.Object).getClass() as Class<T>
It can be called on an instance of a class, for example:
println(Foo().javaClass) //class Foo
However, Foo::javaClass
give you a property reference of type KProperty1<Foo, Class<Foo>>
instead of a Java class instance which can be used to get the class of an instance of Foo
through reflection:
val p: KProperty1<Foo, Class<Foo>> = Foo::javaClass
println(p.get(Foo())) //p.get(Foo()) returns a Java class Foo
Therefore, it is wrong to pass a KProperty
to LoggerFactory.getLogger()
which accepts a Java class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With