要初始化我的记录器,显然我需要:
val LOGGER : Logger = LoggerFactory.getLogger(Foo::javaClass);
如果我这样做:
getLogger
它抱怨参数类型与Class<Foo>
不兼容。但是根据API,两者都是{{1}}。他们有什么不同?
答案 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
Foo
和java
属性KClass
定义为
val <T> KClass<T>.java: Class<T>