访问没有实例的Kotlin委托类型
我已经阅读Kotlin中访问属性委托,这是关于从实例访问委托。 可以从Kotlin 1.1开始使用KProperty::getDelegate
,但是这将返回委托的实例,因此需要先创建一个类的实例。
现在我想获得委托的类型,而没有类的实例。 考虑一个具有自定义委托类型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 <Example>,但不是一个例子的实例,获取委托给CustomDelegate的所有属性?
你可以根据你的需要用两种方法做到这一点。
首先,你必须在build.gradle
文件中包含kotlin-reflect依赖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
和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" } ?: 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
属性2。