为什么Kotlin做了空校验仍需非空断言?Retrofit响应处理场景
if (response.isSuccessful && response.body() != null) { val result = response.body().result }
为什么请求成功时
response.body()仍可能为null Retrofit 中response.isSuccessful仅表示HTTP响应状态码处于200~299区间,满足该条件时仍存在多种body为空的场景:
- HTTP规范约定204(No Content)、205(Reset Content)状态码的响应不携带任何body内容,此时body固定为null
- 服务端实现不符合规范,返回200类成功状态码但实际未返回响应体,或响应体内容与定义的反序列化类型不匹配导致解析结果为空
- 自定义配置的Retrofit Converter处理响应时异常返回null
为什么添加空校验后仍提示智能转换失败
Kotlin的智能转换仅对不可变、返回值可确定不会发生变化的表达式生效。response.body()是Retrofit Response类对外暴露的Java方法,Kotlin编译器无法保证多次调用该方法会返回相同的结果——即使第一次调用判空为true,第二次调用仍存在返回null的可能,因此无法完成智能转换,会要求添加非空断言。
推荐修复方案
无需使用非空断言,更安全的写法如下:
- 先将响应体赋值给本地不可变变量再校验
if (response.isSuccessful) { val body = response.body() if (body != null) { val result = body.result // 执行后续业务逻辑 } }
本地val变量的值不可变,判空后可直接触发智能转换。
- 用空安全操作符简化写法
response.body()?.takeIf { response.isSuccessful }?.let { body -> val result = body.result // 执行后续业务逻辑 }
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

