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

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

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

如果我做:

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

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

javaClass必须在具体实例上调用,因为它被定义为所有类型的扩展属性,而class.java可以在像Foo这样的简单类上调用,以获得Java Class<?>

你可以将::javaClass与接收者结合使用,例如,如果Foo是使用默认构造函数创建的,则可以这样说:

Foo::javaClass.get(Foo())

甚至更简单: Foo().javaClass

这实际上会得到与class.java相同的结果:Java Class<?>表示。

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>>的属性引用 ,而不是可以通过反射来获取Foo实例类的Java类实例:

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

因此,将KProperty传递给接受Java类的LoggerFactory.getLogger()是错误的。

Foo::javaClass是对val定义的引用

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

所以你不得不在foo.javaClass的Foo实例上调用它。

Foo::class为您提供了Foo的实际KClass ,而javaKClass定义的属性

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