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
,而java
是KClass
定义的属性
val <T> KClass<T>.java: Class<T>