访问没有实例的Kotlin委托类型
我已阅读Access property delegate in Kotlin这是关于从实例访问委托的。自Kotlin 1.1以来,可以使用KProperty::getDelegate
,但是这将返回委托的实例,因此需要首先使用该类的实例。访问没有实例的Kotlin委托类型
现在我想获得没有类的实例的委托类型。考虑库与自定义的委托类型CustomDelegate
希望的得到被委派给的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
一个实例,获取所有委托给CustomDelegate
的房产?
我怎样才能,给我KClass <例>,但不 实例的实例,让下放给CustomDelegate所有属性?
根据您的需要,您可以通过两种方式来完成。
首先,你必须包括科特林,反映您的build.gradle
文件依赖性:
compile "org.jetbrains.kotlin:kotlin-reflect:1.1.51"
在我看来,你应该使用,如果你能第一个解决方案,因为它是最清晰的并进行了优化。第二种解决方案可以处理第一种解决方案无法解决的一种情况。
首先
您可以循环的声明的属性和检查属性或委托的类型的类型是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
的源代码,你可以看到一个代表团是如何实现的。所以,你可以这样做:
// 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" } ?: [email protected] false
} catch (t: Throwable) {
// Catch KotlinReflectionInternalError.
[email protected] 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
作为结果。
使用第一种解决方案,是否可以映射委托字段和委托字段?由于我的委托属性必须全部从一个接口继承,这将使得仅仅返回'delegatedProperty2' – msrd0
@ msrd0是的,你可以。你可以改变条件:CustomDelegate :: class.java == property.javaField?.type'到条件'CustomDelegate :: class.java == property.javaField?.type && property.returnType。isSubtypeOf(MyInterface的:: class.starProjectedType)' –