2017-10-08 47 views
4

要初始化我的記錄顯然我需要:Foo :: class.java和Foo :: javaClass有什麼區別?

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

如果我做的:

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

它抱怨說,參數類型是不兼容getLogger。但根據API,兩者都是Class<Foo>。他們有什麼不同?

回答

5

javaClassKClass一個屬性是返回運行Java類實例化對象擴展屬性。在你的情況下,它被用作屬性參考,它會給你一個KProperty1<Foo, Class<Foo>>代表的擴展功能本身:

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

你可以結合一個接收器,例如使用如果Foo提供一個默認的構造函數,你可以說:

Foo::javaClass.get(Foo()) 

可以簡化爲:

Foo().javaClass 

,另一方面利用::class.java,使您的Java Class<?>直接在"class references"描述。在一個簡單的例子,所有三種可能性:

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 
2

Foo::javaClass是一個val參考定義爲

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

所以你必須把它像foo.javaClass美孚的一個實例。

Foo::class給你的Foojava實際KClass是被定義爲

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

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給你,而不是一個Java類的實例可以用來獲取KProperty1<Foo, Class<Foo>>類型的property reference通過反射的類的Foo一個實例:

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

因此,這是錯誤的傳遞KPropertyLoggerFactory.getLogger()它接受一個Java類。

相關問題