Kotlin如何确保泛型参数是接收器类的超类

时间:2018-06-08 08:09:27

标签: generics reflection kotlin

我试图实现快速字段访问器功能,并且还想确保指定的类(字段的真正所有者)是接收器类型的超类,因此我将其编写如下:

inline fun <A : B, reified B: Any> A.getProperty (name: String): Any {
    return B::class.java.getDeclaredField(name).apply { isAccessible = true }.get(this)
}

但是这让我在调用期间无意义地写了接收器类型:

// in SubClass
getProperty<SubClass, BaseClass>("fieldThatIsInBaseClass")

如果在当前类中定义了字段,它甚至不需要参数让我惊讶:

// in BaseClass
getProperty("fieldThatIsInBaseClass")

我还尝试在函数中添加字段类型参数,但是会破坏上面的代码,并且在每种情况下都必须指定所有参数:

inline fun <A : B, reified B: Any, T> A.getProperty (name: String): T {
    @Suppress("UNCHECKED_CAST")
    return B::class.java.getDeclaredField(name).apply { isAccessible = true }.get(this) as T
}

例如,这会破坏事情:

// in a class Example which declares the field
getProperty<Example, Example, Int>("someIntField")

定义字段的类中的理想语法应为:

getProperty<Int>("someIntField")

对于扩展某些基类的类:

getProperty<BaseClass, Int>("fieldThatIsInBaseClass")

这样的事情可能吗?

1 个答案:

答案 0 :(得分:1)

为什么你需要A?如果您将其替换为B

inline fun <reified B: Any> B.getProperty (name: String): Any {
    return B::class.java.getDeclaredField(name).apply { isAccessible = true }.get(this)
}

它还接受B的任何子类型。