Kotlin如何通过反射获取实现指定接口的伴生对象实例并构建映射
问题根源
你当前的过滤逻辑存在偏差:实现Fooable接口的不是Impl1、Impl2这类外层业务类,而是它们内部声明的名为Foo的伴生对象类,直接判断外层类是否实现Fooable永远无法匹配到正确的目标,自然拿不到对应的伴生对象实例。
解决方案
提供两种实现方式,可根据项目依赖情况选择:
方案1:纯Java反射实现(无需额外依赖)
直接利用Kotlin编译伴生对象生成的静态INSTANCE字段拿单例:
fun mapImplToFooable(): Map<String, Fooable> { return findAllClasses() // 过滤出内部包含符合要求的Foo伴生对象的外层类 .filter { implClass -> implClass.declaredClasses.any { nestedClass -> nestedClass.simpleName == "Foo" && Fooable::class.java.isAssignableFrom(nestedClass) } } .associate { implClass -> // 找到对应伴生类 val fooCompanionClass = implClass.declaredClasses.first { it.simpleName == "Foo" && Fooable::class.java.isAssignableFrom(it) } // 从静态INSTANCE字段取伴生对象单例 val fooInstance = fooCompanionClass.getField("INSTANCE").get(null) as Fooable // 用外层类的简单名作为key,和你之前硬编码的逻辑对齐 implClass.simpleName to fooInstance } }
方案2:Kotlin反射实现(代码更简洁)
需要提前引入kotlin-reflect依赖,直接调用Kotlin反射API获取伴生对象:
import kotlin.reflect.full.companionObject import kotlin.reflect.full.companionObjectInstance fun mapImplToFooable(): Map<String, Fooable> { return findAllClasses() .mapNotNull { implClass -> val kClass = implClass.kotlin // 校验伴生对象名称+类型符合约定 if (kClass.companionObject?.simpleName != "Foo") return@mapNotNull null val fooInstance = kClass.companionObjectInstance as? Fooable ?: return@mapNotNull null implClass.simpleName to fooInstance } .toMap() }
内容的提问来源于stack exchange,提问作者Matthew Layton
相关产品推荐
相关产品推荐

