Kotlin Android 反射在运行时得到 class

Kotlin Android reflection get class in runtime

我收到服务器的响应,returns 我有不同的对象,每个对象都有一个类型。我如何在运行时将 class 与我从响应中获得的类型相匹配?例如,此代码有效,但我试图摆脱 when 语句并使其更具动态性。

sealed class Tile(
    private val id: String,
    private val type: String,
    private val title: String,
) {
    class RedTile(
        id: String,
        type: String,
        title: String,
        val stuff: String
    ) : Tile(id, type, title) {
        companion object {
            const val TYPE = "RedTile"
        }
    }
    class BlueTile(
        id: String,
        type: String,
        title: String,
        val value: Int
    ) : Tile(id, type, title) {
        companion object {
            const val TYPE = "BlueTile"
        }
    }

    companion object {
        fun parseArray(jsonArrayString: String): List<Tile> {
        return JsonParser.parseString(jsonArrayString).asJsonArray
            .map { tileJsonObject ->
                tileJsonObject as JsonObject
                val tile = when (tileJsonObject.get("type").asString) {
                    Red.TYPE -> Red::class.java
                    Blue.TYPE -> Blue::class.java
                    else -> Red::class.java
                }
                Gson().fromJson(tileJsonObject, tile)
            }
    }
    }
}

使用静态 when 并不是那么糟糕,但我建议将其移至单独的 Tile.getTileClassByType() 函数以保持代码整洁。如果您更喜欢动态搜索 类,则可以使用以下内容:

companion object {
    private val tileClassesByType = Tile::class.sealedSubclasses
        .associateBy { it.simpleName!! }
    
    fun parseArray(jsonArrayString: String): List<Tile> {
        ...
        val tile = getTileClassByType(tileJsonObject.get("type").asString) ?: RedTile::class
        Gson().fromJson(tileJsonObject, tile.java)
        ...
    }

    fun getTileClassByType(type: String): KClass<out Tile>? = tileClassesByType[type]
}

以下是我的原回答,没有在问题中提供详细信息。不鼓励这样做,因为最好避免按名称动态加载 类。


您可以使用 Java 标准库中的 Class.forName()

val type = tileJsonObject.get("type").asString
Class.forName("com.example.$type")

请注意您在 type 字段中收到的内容。如果此数据不受信任,那么您应该在使用前对其进行验证,这样另一方就无法在您的应用程序中实例化任意 类 的对象。