簡體   English   中英

如何使用反射和接口調用 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類的名稱映射到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 { ... }

到目前為止,我所擁有的是一個函數,它能夠找到一個包和子包中的所有類:

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()

問題在於clazzClass<Fooable>而不是Fooable的實例(在每種情況下,都是伴隨對象)。

如何獲取伴隨對象實例,而不僅僅是Class<Fooable>

使用 Kotlin 反射 API(而不是 Java API),以便您可以訪問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 
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM