为什么SomeClass :: class是KClass ,但是这个:: class是KClass

我想打印我的类的属性的值。

fun print() { val cl = this::class cl.declaredMemberProperties.filter {it.visibility != KVisibility.PRIVATE}.forEach { println("${it.name} = ${it.get(this)}") } } 

当我尝试构建此代码时,出现编译器错误:

 Error:(34, 40) Kotlin: Out-projected type 'KProperty1' prohibits the use of 'public abstract fun get(receiver: T): R defined in kotlin.reflect.KProperty1' 

当我改变this类名SomeClass一切都很好

 fun print() { val cl = SomeClass::class cl.declaredMemberProperties.filter {it.visibility != KVisibility.PRIVATE}.forEach { println("${it.name} = ${it.get(this)}") } } 

所以问题是this::class编译器KClass器types为KClass而不是使用KClass 。 任何想法为什么会发生?

造成这种差别的原因是,当使用SomeClass::class引用时,肯定是表示SomeClass的类标记,而不是其可能的派生类,因此它是KClass没有types投影。

但是this::class写在一个openabstract类或扩展函数函数中的类可以返回一个派生类的类标记,因此,为了确保types的安全性, types是out KClassKClass意味着实际的types参数可以是SomeClass或其子types。

例:

 open class A { fun f() { println(this::class) // KClass because it can be KClass } } class B : A() B().f()