You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从API获取数据时,Any转Integer抛出NullPointerException求助

解决Any转Int时的NullPointerException问题

问题根源

代码里连续使用!!强制非空,加上total字段定义为Any?模糊类型,一旦API返回的total不是Int类型(比如字符串格式的数字)、或者artistStatsItem/albums/total任意一个为null,都会触发NullPointerException。

解决方案

方案1:优化数据类字段类型(推荐)

尽量避免使用Any?,让序列化库直接将total解析为Int?;若API返回的total存在数字/字符串两种格式,可自定义类型转换器兼容:

  1. 修改数据类字段:
data class Album(
    @field:SerializedName("created")
    val created: Int? = null,

    @field:SerializedName("total")
    val total: Int? = null, // 直接定义为Int?,让序列化库自动转换

    @field:SerializedName("coming")
    val coming: Int? = null
)
  1. 兼容字符串格式数字的自定义转换器(以Gson为例):
    如果API返回的total有时是"123"(字符串)有时是123(数字),编写TypeAdapter处理:
class IntOrStringAdapter : TypeAdapter<Int>() {
    override fun write(out: JsonWriter, value: Int?) {
        out.value(value)
    }

    override fun read(`in`: JsonReader): Int? {
        return when (`in`.peek()) {
            JsonToken.NUMBER -> `in`.nextInt()
            JsonToken.STRING -> `in`.nextString().toIntOrNull()
            else -> {
                `in`.skipValue()
                null
            }
        }
    }
}

给total字段添加注解:

@JsonAdapter(IntOrStringAdapter::class)
@field:SerializedName("total")
val total: Int? = null

方案2:安全处理现有Any?类型的转换

若必须保留Any?类型,用安全调用和类型判断替代!!,同时设置兜底默认值:

val albums by remember {
    val totalValue = artistStatsItem?.albums?.total?.let { rawValue ->
        when (rawValue) {
            is Int -> rawValue
            is String -> rawValue.toIntOrNull() // 字符串转Int,失败返回null
            else -> null // 其他类型直接返回null
        }
    } ?: 0 // 任何一步为空/转换失败,用0作为默认值(可根据业务调整)
    mutableIntStateOf(totalValue)
}

关键提醒

  • 禁止连续使用!!,这是运行时空指针的高发原因,改用?.安全调用、?: Elvis表达式处理空值场景。
  • 数据类字段类型尽量和API返回的实际数据类型匹配,减少模糊类型的使用,提前在编译期规避类型转换风险。

内容的提问来源于stack exchange,提问作者Arthur Thuma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 17:27:24