Foo :: class.java和Foo :: javaClass有什么区别?

时间:2017-10-08 04:11:34

标签: kotlin

要初始化我的记录器,显然我需要:

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

如果我这样做:

getLogger

它抱怨参数类型与Class<Foo>不兼容。但是根据API,两者都是{{1}}。他们有什么不同?

3 个答案:

答案 0 :(得分:9)

KProperty1<Foo, Class<Foo>>是一个扩展属性,它返回实例化的对象运行时Java类。在您的情况下,它被用作属性引用,它将为您提供表示扩展函数本身的val T.javaClass: java.lang.Class<T>

Foo

您可以将它与接收器结合使用,例如:如果Foo::javaClass.get(Foo()) 提供了默认构造函数,您可以说:

Foo().javaClass

可以简化为:

::class.java

另一方面,使用Class<?>可直接为"class references"中的Java 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 提供。所有三种可能性都在一个简单的例子中:

E extends Entry<K, V>

答案 1 :(得分:6)

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为您提供property reference类型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传递给接受Java类的LoggerFactory.getLogger()是错误的。

答案 2 :(得分:2)

Foo::javaClass是对val定义为

的引用
inline val <T : Any> T.javaClass: Class<T>

所以你必须在像foo.javaClass这样的Foo实例上调用它。

Foo::class为您提供实际KClass Foojava属性KClass定义为

val <T> KClass<T>.java: Class<T>