【问题标题】:Pass DataType of the Class传递类的DataType
【发布时间】:2019-11-07 10:43:42
【问题描述】:

我有如下数据类,里面存储了两个值,JSON 和 dataType:

data class DataTypeItem(
    var json     : String = "",
    var dataType : Class<*> ?= null
)

我按以下方式定义了列表:

val dataTypeList = mutableMapOf<String, DataTypeItem>()

dataTypeList.put( "item_1", DataTypeItem( json1, MyDataType::class.java ) )
dataTypeList.put( "item_2", DataTypeItem( json1, List<MyDataType>::class.java ) )

请注意,在一种情况下,我使用 MyDataType 作为 DataType,而在另一种情况下使用 List 。

现在我想遍历每个 dataTypeList 项并将给定数据类型的 JSON 解析到它的模型中:

fun init()
{
    dataTypeList.forEach {
        dataTypeItem ->
            val model = Gson().fromJson( dataTypeItem.value.json, dataTypeItem.value.dataType::class.java )
    }
}

我正在使用以下模型:

data class dataTypeItem(
    @SerializedName("sqlId")
    val sqlId: String,
    @SerializedName("name")
    val name: String
)

但我不断收到运行时异常:

Attempted to deserialize a java.lang.Class. Forgot to register a type adapter?

另外,如果是列表,我需要在 Gson().fromJSON(..) 上调用 toList():

fun init()
{
    dataTypeList.forEach {
        dataTypeItem ->
            val model;

            if( dataTypeItem.value.dataType::class.java is Array )
                model = Gson().fromJson( dataTypeItem.value.json, dataTypeItem.value.dataType::class.java ).toList()
            else
                model = Gson().fromJson( dataTypeItem.value.json, dataTypeItem.value.dataType::class.java )
    }
}

如何动态传递 dataType 并区分它是 List/Array 还是直接类?此外,每当我尝试调用 toList() 时,都会收到一个未定义的错误。

如果我直接指定类,那么它工作正常

 var model = Gson().fromJson( json, DataTypeItem::class.java )

 var model = Gson().fromJson( json, Array<DataTypeItem>::class.java )

但我需要能够将其动态指定为参数

【问题讨论】:

  • 当您收到此错误时,您尝试反序列化的类是什么?

标签: json kotlin gson deserialization


【解决方案1】:

这段代码运行良好:

val dataTypeMap = mapOf(                                                                                                                              
    "item_1" to MyDataTypeItem("""{"sqlId" : "1",  "name" : "a"}""", MyDataType::class.java),                                                           
    "item_2" to MyDataTypeItem("""[{"sqlId" : "1",  "name" : "a"}, {"sqlId" : "2",  "name" : "b"}]""", Array<MyDataType>::class.java)                  
)                                                                                                                                                     

val result = dataTypeMap.map{ Gson().fromJson(it.value.json, it.value.dataType) }                                                                                       

我将DataTypeItem 重命名为MyDataTypeItem 并将dataTypeItem 重命名为MyDataType

为什么需要调用 toList()?如果确实有必要,您可以改为执行以下操作:

val result = dataTypeMap.map {                                                                                           
    if (it.value.dataType?.isArray == true) Gson().fromJson<Array<*>>(it.value.json, it.value.dataType).toList()        
    else Gson().fromJson(it.value.json, it.value.dataType)                                                              
}  

【讨论】:

  • 非常感谢!我犯了一个愚蠢的错误,并使用了这样的变量 dataTypeItem.value.dataType::class.java 而不是 dataTypeItem.value.dataType。我仍然面临的一个问题是它似乎没有检测到它是一个数组,我尝试了 when(it.value.dataType) 但它仍然总是进入 else 条件。请问有什么提示吗?谢谢!
  • 没问题 ;)。你是对的,之前的代码是错误的,但我相信它现在可以工作了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 2019-09-20
  • 2022-10-21
  • 1970-01-01
相关资源
最近更新 更多