在 String 类型的可为空的接收器上只允许安全或非空断言调用?

Only safe or non-null asserted calls are allowed on a nullable receiver of type String?

我的 api 回复有数据 class,如下

data class ApiResponse(
@SerializedName("ErrorCode") @Expose
var errorCode: Int = 0,
@SerializedName("Message")
@Expose
var message: String? = null,

@SerializedName("Token")
@Expose
var token: String? = null,

@SerializedName("UserId")
@Expose
var userId: String? = null,

@SerializedName("DOB")
@Expose
var birthdate: String? = null,

@SerializedName("Mobile")
@Expose
var mobile: String? = null,

@SerializedName("Data")
@Expose
var dataList: MutableList<Data?>? = null
)

我的api电话

val request = ApiServiceBuilder.buildService(NetworkCall::class.java)
    request.login(apiPost = ApiPost("long","hello")).enqueue(object :Callback<ApiResponse>{
        override fun onResponse(call: Call<ApiResponse>, response: Response<ApiResponse>) {
            Log.e("resopne",response.body().userId)
        }

        override fun onFailure(call: Call<ApiResponse>, t: Throwable) {
            t.printStackTrace()
            Log.e("resopne","error")
        }
    })

在尝试获取 userId 时我得到了

在可空对象上只允许安全或非空断言调用

您已通过在类型前面放置 ? 将模型 class 中的 userId 定义为 optional or nullable

@SerializedName("UserId")
@Expose
var userId: String? = null

因此,当从 response.body() 中读取值时,它告诉您 response.body() 中的值 userId 可能为 null,并且会在运行时抛出 null-pointer exception。所以,为了保护它,它给了你两个选择:

1) Only safe userId? -> 这意味着如果该值为 null 则它将不会继续执行该特定行。

2) Non-null asserted userId!! -> 意味着你告诉编译器它永远不会为 null 并且你保证如果这个值有任何机会为 null 那么它会抛出运行时 null-pointer exception.

因此,最佳做法是为 Only Safe 设置 ? 并以这种方式使用它,因为如果它始终是 not-null 则不会有任何区别。