我读过 Access property delegate in Kotlin,它是关于从实例访问委托(delegate)的。从 Kotlin 1.1 开始就可以使用 KProperty::getDelegate,但是这将返回委托(delegate)的实例,因此首先需要一个类的实例。

现在我想在没有类的实例的情况下获取委托(delegate)的类型。考虑一个具有自定义委托(delegate)类型 CustomDelegate 的库,它想要获取委托(delegate)给 CustomDelegate 实例的类的所有属性:

class Example
{
    var nonDelegatedProperty = "I don't care about this property"
    var delegatedProperty1 by lazy { "I don't care about this too" }
    var delegatedProperty2 by CustomDelegate("I care about this one")
}

鉴于我有 KClass<Example> ,但没​​有 Example 的实例,我如何才能将所有属性委托(delegate)给 CustomDelegate

最佳答案



您可以根据需要通过两种方式进行操作。

首先,您必须在 build.gradle 文件中包含 kotlin-reflect 依赖项:

compile "org.jetbrains.kotlin:kotlin-reflect:1.1.51"

在我看来,如果可以,您应该使用第一种解决方案,因为它是最清晰和优化的解决方案。相反,第二种解决方案可以处理第一种解决方案不能处理的情况。

第一个

您可以循环声明的属性并检查属性的类型或委托(delegate)的类型是否为 CustomDelegate
// Loop on the properties of this class.
Example::class.declaredMemberProperties.filter { property ->
    // If the type of field is CustomDelegate or the delegate is an instance of CustomDelegate,
    // it will return true.
    CustomDelegate::class.java == property.javaField?.type
}

此解决方案只有一个问题,您还将获得 CustomDelegate 类型的字段,因此,给出以下示例:
class Example {
    var nonDelegatedProperty = "I don't care about this property"
    val delegatedProperty1 by lazy { "I don't care about this too" }
    val delegatedProperty2 by CustomDelegate("I care about this one")
    val customDelegate = CustomDelegate("jdo")
}

你会得到 delegatedProperty2customDelegate 。如果您只想获得 delegatedProperty2 ,我找到了一个可怕的解决方案,如果您需要管理这种情况,可以使用它。

第二个

如果您查看 KPropertyImpl 的源代码,您可以看到委托(delegate)是如何实现的。所以,你可以做这样的事情:
// Loop on the properties of this class.
Example::class.declaredMemberProperties.filter { property ->
    // You must check in all superclasses till you find the right method.
    property::class.allSuperclasses.find {
        val computeField = try {
            // Find the protected method "computeDelegateField".
            it.declaredFunctions.find { it.name == "computeDelegateField" } ?: return@find false
        } catch (t: Throwable) {
            // Catch KotlinReflectionInternalError.
            return@find false
        }

        // Get the delegate or null if the delegate is not present.
        val delegateField = computeField.call(property) as? Field
        // If the delegate was null or the type is different from CustomDelegate, it will return false.
        CustomDelegate::class.java == delegateField?.type
    } != null
}

在这种情况下,您只会得到 delegatedProperty2 作为结果。

关于reflection - 在没有实例的情况下访问 Kotlin 委托(delegate)类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46870280/

10-14 12:37
查看更多