Why Android Studio show error when I use No.2 script. I found no different between 1 and 2.

class Adapter {
    var nameList : ArrayList<String>? = null
}

class Program {
    private fun send() {
        val list: ArrayList<String> = ArrayList()
        val adapter = Adapter()

// Case 1
        var otherList = adapter.nameList
        if (otherList != null) {
            list.addAll(otherList) // <--- no error
        }

// Case 2
        if (adapter.nameList!=null) {
            list.addAll(adapter.nameList) // <--- Error here
            // Smart cast to 'kotlin.collections.ArrayList<String> /* = java.util.ArrayList<String> */' is impossible, because 'adapter.nameList' is a mutable property that could have been changed by this time
        }
    }
}

请解释一下这个案子

推荐答案

The IDE should give you a warning, explaining that after the null check, it's possible that adapter.nameList was changed by another thread, and that when you call list.addAll(adapter.nameList), adapter.nameList could actually be null by that point (again, because a different thread could have changed the value. This would be a race condition).

你有几个解决方案:

  1. nameList设为val,其参考号为final.因为它是最终版本,所以保证另一个线程无法更改它.这可能不适合您的用例.

    class Adapter {
        val nameList : ArrayList<String>? = null
    }
    
  2. Create a local copy of name list before you do the check. Because it's a local copy, the compiler knows that another thread can't access it, and thus it can't be changed. The local copy could be defined with either a var or a val in this case, but I recommend val.

    val nameList = adapter.nameList
    if (nameList != null) {
        list.addAll(nameList)
    }
    
  3. 使用Kotlin为这种情况提供的一个实用函数.let函数使用内联函数复制作为参数调用的引用.这意味着它可以有效地编译成与#2相同的格式,但它更简洁一些.I prefer this solution.

Kotlin相关问答推荐

在Kotlin中可以连接两个范围吗?

处理合成层次 struct 中的深层按钮以切换视图

两个LocalDateTime之间的Kotlin差异

禁用 Gradle执行消息

Mockk:对同一函数进行两次存根会忽略第一个行为

Kotlin 说不需要强制转换,但删除后会出现新警告

在 Kotlin 中,为什么我们要在闭包中捕获值

如何在 kotlin 中的数据类中为变量提供多种类型

try 一次性插入多条记录时,JOOQ连接为空错误

Kotlin 如何使用其 get 函数在内部检索映射值

如何在 kotlin 中创建自定义迭代器并添加到现有类?

如何在 Kotlin 中声明一个空数组而不期望 null?

如何使用子变量在 Kotlin 中初始化父级

Jetpack BottomNavigation - java.lang.IllegalStateException:Already attached to lifecycleOwner

在java代码中使用kotlin库

Kotlin not nullable值可以为null吗?

未找到导入 kotlinx.coroutines.flow.*

在kotlin中初始化类变量的正确位置是什么

Kotlin out-projected 类型禁止使用

Kotlin - 如果不为空,则使用修改后的 Obj props 覆盖 Obj props