使用一个函数将Json转换为多种类型

时间:2019-11-02 16:55:46

标签: android generics kotlin

我写了一个Java应用程序,从JSON中的API检索数据。取决于端点,实际数据可能差异很大。因此,我做了一个函数,将每个可能的类的数据转换为所需的类。这给我提供了多个函数,这些函数仅在要转换为的类类型上有所不同。以下是两个示例:

public List<ZermeloBranch> processBranches(ZermeloApiResponseObject responseObject) {
        List<ZermeloBranch> branches = new ArrayList<>();
        List<LinkedTreeMap> branchMaps = responseObject.getData();
        Gson gson = new Gson();
        for (LinkedTreeMap treeMap : branchMaps) {
            branches.add(gson.fromJson(gson.toJsonTree(treeMap).toString(), ZermeloBranch.class));
        }
        return branches;
    }

public List<ZermeloAnnouncement> processAnnouncements(ZermeloApiResponseObject responseObject) {
        List<ZermeloAnnouncement> announcements = new ArrayList<ZermeloAnnouncement>();
        List<LinkedTreeMap> announcementMaps = responseObject.getData();
        Gson gson = new Gson();
        for (LinkedTreeMap treeMap : announcementMaps) {
            announcements.add(gson.fromJson(gson.toJsonTree(treeMap).toString(), ZermeloAnnouncement.class));
        }
        return announcements;
    }

现在,我将这个应用程序重写为Kotlin,我想应该可以编写一个函数来处理将要传递给类的数据解码为参数。因此,我使ZermeloBranch和ZermeloAnnouncement都继承自ZermeloDataObject。我想编写一个这样的函数:

fun processDataToList(data:JSONArray, convertToClass:KClass<out ZermeloDataObject>):List<KClass<out ZermeloDataObject>>{
    val returnList:ArrayList<KClass<out ZermeloDataObject>> = arrayListOf()
    val gson = Gson()
    for (item in 0 until data.length()){
        returnList.add(gson.fromJson(item, convertToClass))
    }
    return returnList
}

并用processDataToList(data, ZermeloAnnouncements::class)调用并返回List<ZermeloAnnoucement>,用processDataToList(data, ZermeloBranch::class)调用并返回List<ZermeloBranch>。 las,编译器给我gson.fromJson一个错误,指出“以下任何一个函数都不能用提供的参数调用”,然后列出所有可能的函数。

是否可以按照我的建议使用一个函数,如果是的话,我在做什么错了?

1 个答案:

答案 0 :(得分:1)

您可以使用 ng build --prod 提供的 ngsw 正确处理返回类型。 此外,您正在传递 TypeToken 而不是数据

Gson

index

相反,您可以在一行代码中完成全部操作。检查以下内容:

val type = object: TypeToken<KClass<out ZermeloDataObject>>() {}.type

除此之外,您还可以使用以下更通用的样式:

fun processDataToList(data:JSONArray, convertToClass:KClass<out ZermeloDataObject>):ArrayList<KClass<out ZermeloDataObject>>{
    val returnList:ArrayList<KClass<out ZermeloDataObject>> = arrayListOf()
    val type = object: TypeToken<KClass<out ZermeloDataObject>>() {}.type
    val gson = Gson()

    for (item in 0 until data.length()){
        returnList.add(gson.fromJson(data[item].toString(), type))
    }

    return returnList
}

或者简单地

fun processDataToList(data:JSONArray, convertToClass:KClass<out ZermeloDataObject>):List<KClass<out ZermeloDataObject>>{
    return Gson().fromJson(data.toString(), object: TypeToken<List<KClass<out ZermeloDataObject>>>() {}.type)
}