Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between Foo::class.java and Foo::javaClass?

Tags:

kotlin

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?

like image 454
jingx Avatar asked Oct 08 '17 04:10

jingx


People also ask

What is difference between class and class in Java?

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 in Java?

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.


2 Answers

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
like image 78
s1m0nw1 Avatar answered Oct 23 '22 20:10

s1m0nw1


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.

like image 21
BakaWaii Avatar answered Oct 23 '22 18:10

BakaWaii