Kotlin技术问题:已知B实例引用,如何确定其在A中的属性名
解决方案:通过Kotlin反射从B实例定位A中对应的属性名称
核心思路
利用B实例持有的A引用,遍历A的所有成员属性,逐一比对属性值与目标B实例的引用是否一致,找到匹配的属性名称。
实现步骤
- 从B实例中取出关联的A对象(即
b1.myA); - 通过Kotlin反射获取A类的所有声明成员属性(包括私有属性);
- 过滤出类型为
B的属性,缩小排查范围; - 为私有属性设置可访问权限,获取属性在A实例上的实际值;
- 比对属性值与当前B实例的引用,找到匹配项后返回属性名称。
代码实现
import kotlin.reflect.full.declaredMemberProperties import kotlin.reflect.jvm.isAccessible // 给B类添加扩展函数,直接获取对应A中的属性名 fun B.findCorrespondingPropertyNameInA(): String? { val aInstance = this.myA return aInstance::class.declaredMemberProperties // 只保留返回类型为B的属性 .filter { it.returnType.classifier == B::class } // 开启私有属性的访问权限 .onEach { it.isAccessible = true } // 找到属性值与当前B实例引用完全一致的属性 .firstOrNull { it.get(aInstance) == this } // 返回属性名称,无匹配则返回null ?.name }
测试验证
fun testIt(){ val a = A() val b1 = a.listOfB[0] println(b1.findCorrespondingPropertyNameInA()) // 输出:myFirstB val b2 = a.listOfB[1] println(b2.findCorrespondingPropertyNameInA()) // 输出:mySecondB }
注意事项
- 由于A中的属性是私有访问权限,必须通过
isAccessible = true开启反射访问权限,否则会抛出访问异常; - 这里使用引用相等判断(Kotlin中对象默认
==为引用比较),确保匹配的是同一个实例; - 如果A中存在多个属性引用同一个B实例,该方法会返回第一个匹配到的属性名称。
内容的提问来源于stack exchange,提问作者Manuel Rossetti
相关产品推荐
相关产品推荐

