为什么SomeClass :: class是KClass <someclass>但是这个:: class是KClass <out someclass =“”>

时间:2017-03-28 12:44:38

标签: reflection kotlin

我想打印班级属性的值。

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<out SomeClass, Any?>' 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::classKClass<out SomeClass>而不是KClass<SomeClass>。知道为什么会这样吗?

1 个答案:

答案 0 :(得分:7)

这种差异的原因在于,当您使用SomeClass::class引用时,它肯定是表示SomeClass的类令牌而不是其可能的派生类之一,因此它是{{ 1}}没有类型投影。

但是在KClass<SomeClass>this::class类或扩展函数的函数中编写的open可以返回派生类的类标记,因此,为了确保类型安全,{ {3}}:abstract表示实际的类型参数可以是KClass<out SomeClass>或其子类型。

示例:

SomeClass