我读过 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")
}
你会得到
delegatedProperty2
和 customDelegate
。如果您只想获得 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/