如何使用反射和接口调用 Kotlin 伴随对象函数
How to call Kotlin companion object function using reflection and interface
假设我有以下接口:
interface Fooable {
fun foo()
}
该接口由命名伴随对象实现;例如:
class Impl1 {
companion object Foo : Fooable {
fun foo() { ... }
}
}
class Impl2 {
companion object Foo : Fooable {
fun foo() { ... }
}
}
我希望能够将每个 Impl class 的名称映射到一个 Fooable
实例(因为伴随对象总是单例实例);例如:
fun mapImplToFooable(): Map<String, Fooable> = mapOf(
"Impl1" to Impl1.Foo,
"Impl2" to Impl2.Foo
)
然后我可以调用它;例如:
val map = mapImplToFooable()
map["Impl1"]!!.foo()
我想要的是能够使用反射创建地图,而不是硬编码,假设每个 Impl 都有一个 companion object Foo : Fooable { ... }
到目前为止,我所拥有的是一个能够在一个包和子包中找到所有 classes 的函数:
fun findAllClasses(): List<Class<*>> { ... }
由此,我成功走到了这一步:
function mapImplToFooable(): Map<String, Fooable> {
return findAllClasses()
.filter { Fooable::class.java.isAssignableFrom(it) }
.map { clazz -> it.name to clazz } // This is a problem...
.toMap()
问题是 clazz
是 Class<Fooable>
而不是 Fooable
的实例(在每种情况下,都是伴随对象)。
如何获取伴随对象实例,而不仅仅是一个 Class<Fooable>
?
使用 Kotlin 反射 API(而不是 Java),这样您就可以访问 objectInstance
:
fun mapImplToFooable(): Map<String, Fooable> =
findAllClasses()
.filter {
Fooable::class.java.isAssignableFrom(it) &&
it != Fooable::class.java // you should also check this if findAllClasses can return Fooable
}
.associate { // .map { ... }.toMap() can be simplified to associate
// you should get the declaring class's name here
clazz -> clazz.declaringClass.name to clazz.kotlin.objectInstance as Fooable
}
假设我有以下接口:
interface Fooable {
fun foo()
}
该接口由命名伴随对象实现;例如:
class Impl1 {
companion object Foo : Fooable {
fun foo() { ... }
}
}
class Impl2 {
companion object Foo : Fooable {
fun foo() { ... }
}
}
我希望能够将每个 Impl class 的名称映射到一个 Fooable
实例(因为伴随对象总是单例实例);例如:
fun mapImplToFooable(): Map<String, Fooable> = mapOf(
"Impl1" to Impl1.Foo,
"Impl2" to Impl2.Foo
)
然后我可以调用它;例如:
val map = mapImplToFooable()
map["Impl1"]!!.foo()
我想要的是能够使用反射创建地图,而不是硬编码,假设每个 Impl 都有一个 companion object Foo : Fooable { ... }
到目前为止,我所拥有的是一个能够在一个包和子包中找到所有 classes 的函数:
fun findAllClasses(): List<Class<*>> { ... }
由此,我成功走到了这一步:
function mapImplToFooable(): Map<String, Fooable> {
return findAllClasses()
.filter { Fooable::class.java.isAssignableFrom(it) }
.map { clazz -> it.name to clazz } // This is a problem...
.toMap()
问题是 clazz
是 Class<Fooable>
而不是 Fooable
的实例(在每种情况下,都是伴随对象)。
如何获取伴随对象实例,而不仅仅是一个 Class<Fooable>
?
使用 Kotlin 反射 API(而不是 Java),这样您就可以访问 objectInstance
:
fun mapImplToFooable(): Map<String, Fooable> =
findAllClasses()
.filter {
Fooable::class.java.isAssignableFrom(it) &&
it != Fooable::class.java // you should also check this if findAllClasses can return Fooable
}
.associate { // .map { ... }.toMap() can be simplified to associate
// you should get the declaring class's name here
clazz -> clazz.declaringClass.name to clazz.kotlin.objectInstance as Fooable
}