【问题标题】:Android, Kotlin: Creating a GenericTypeIndicator from reflectionAndroid,Kotlin:从反射创建 G​​enericTypeIndicator
【发布时间】:2018-04-23 15:07:55
【问题描述】:

所以我编写了一个将 Firebase 快照反序列化为类的类。我这样做的原因是因为我从 Firebase 获得了一个 String 对象,我实际上想为其实例化一个不同的类。 getValue 不支持此功能,因此我必须解决此问题。

现在一切正常,除了地图部分。 DataSnapshot 确实想要一个 GenericTypeIndicator 作为参数,但由于一切都是动态完成的,我不知道如何通过反射来做到这一点。

这是我当前的代码:

fun <T> deserialize(dataSnapshot: DataSnapshot, clazz: Class<T>): T {
    val obj = clazz.newInstance()

    dataSnapshot.children.forEach {
        val field = try {
            clazz.getDeclaredField(it.key)
        } catch(e: NoSuchFieldException) { return@forEach }

        field.isAccessible = true

        when(field.type){
            Translation::class.java ->
                field.set(obj, Translation(it.getValue(String::class.java)!!))
            Map::class.java -> { /* Here we need to do crazy Map GenericTypeIndicator stuff */ }
            else -> field.set(obj, it.getValue(field.type))
        }
    }

    return obj
}


删除 Map 案例时出现的错误是:

Class java.util.Map has generic type parameters, please use GenericTypeIndicator instead


如果我实际上将 GenericTypeIndicator 与 HashMap 一起使用,它将给我以下错误:

com.google.firebase.database.DatabaseException: Not a direct subclass of GenericTypeIndicator: class java.lang.Object

不是我想这样做,因为这最终必须动态完成。

现在我不知所措,所以任何帮助都将不胜感激,主要是因为每个对象的地图都不同,所以我不能只拥有一个预定义的泛型。

【问题讨论】:

    标签: android firebase reflection kotlin deserialization


    【解决方案1】:

    我通过执行 isAssignableFrom 并为 GenericTypeIndicator 创建一个对象来检测 Map 变量。

    所以唯一需要改变的是代码中的when部分:

    when {
        field.type == Translation::class.java ->
            field.set(obj, Translation(it.getValue(String::class.java)!!))
        Map::class.java.isAssignableFrom(field.type) ->
            field.set(obj, it.getValue(object: GenericTypeIndicator<HashMap<String, Any>>(){}))
        else -> field.set(obj, it.getValue(field.type))
    }
    

    Firebase 只接受字符串作为键,因此我们可以将其固定,虽然它不喜欢使用 * 表示法作为值,但我们可以将其设为 Any,它似乎工作正常。

    我希望这可以帮助其他可能遇到此问题的人 x)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-13
      • 1970-01-01
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      • 2022-10-14
      • 2021-10-29
      相关资源
      最近更新 更多