В чем разница между Foo::class.java и Foo::javaClass?

Для инициализации моего регистратора, по-видимому, мне нужно:

val LOGGER : Logger = LoggerFactory.getLogger(Foo::class.java);

If I do:

val LOGGER : Logger = LoggerFactory.getLogger(Foo::javaClass);

Он жалуется, что тип параметра не совместим с getLogger. Однако, согласно API, оба являются Class<Foo>. Насколько они разные?


person jingx    schedule 08.10.2017    source источник


Ответы (3)


javaClass – это свойство расширения, которое возвращает класс Java среды выполнения созданного экземпляра объекта. В вашем случае он используется как ссылка на свойство, которая даст вам KProperty1<Foo, Class<Foo>>, представляющий саму функцию расширения:

val T.javaClass: java.lang.Class<T>

Вы можете использовать это в сочетании с приемником, например. если бы Foo предоставил конструктор по умолчанию, вы могли бы сказать:

Foo::javaClass.get(Foo())

который можно упростить до:

Foo().javaClass

С другой стороны, использование ::class.java дает вам Java Class<?>, как описано в "ссылки на классы" напрямую. Все три возможности в простом примере:

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
person s1m0nw1    schedule 08.10.2017

javaClass — это свойство расширения, которое возвращает класс Java во время выполнения объекта.

/**
 * 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>

Его можно вызвать для экземпляра класса, например:

println(Foo().javaClass)    //class Foo

Однако Foo::javaClass дает вам ссылку на свойство типа KProperty1<Foo, Class<Foo>> вместо экземпляра класса Java, который можно использовать чтобы получить класс экземпляра Foo через отражение:

val p: KProperty1<Foo, Class<Foo>> = Foo::javaClass
println(p.get(Foo()))    //p.get(Foo()) returns a Java class Foo

Следовательно, неправильно передавать KProperty в LoggerFactory.getLogger(), который принимает класс Java.

person BakaWaii    schedule 08.10.2017

Foo::javaClass — это ссылка на val определенный в качестве

inline val <T : Any> T.javaClass: Class<T>

Так что вам придется вызывать его для экземпляра Foo, например foo.javaClass.

Foo::class дает вам фактическое KClass из Foo, а java является свойством KClass, определенным как

val <T> KClass<T>.java: Class<T>
person tynn    schedule 08.10.2017