访问没有实例的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 customDelegatecustomDelegate 。 如果你只想得到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。