首页 > 解决方案 > 两个 observables 指向同一个引用

问题描述

我编写了以下示例并检查了对象 a 和 b 的 observerA 变量的值。

例子

class Test {
    val observerA = Observer<String>{}
}

查看

val a = Test()
val b = Test()
AppLogger.LOGE("[A]ObserverA: ${a.observerA} [B]ObserverA: ${b.observerA}")

结果

[A]ObserverA: com.test.Test$observerA$1@e3d8a1b  
[B]ObserverA: com.test.Test$observerA$1@e3d8a1b

我的猜测是 a.observerA 和 a.observerA 应该不同,但它们指的是同一个对象。

当我如下写observerA时,我看到创建了不同的对象。我不知道为什么会出现这种差异。

val observerA = object : Observer<String>{
    override fun onChanged(t: String?) {

    }
}

标签: javaandroidkotlin

解决方案


当你使用这个语法时,你定义了一个空主体的 lambda:

Observer<String>{}

这个 lambda 将被编译成一个匿名类。如果 lambda 没有捕获任何变量,作为优化步骤,它将只有一个实例(因为无论如何您都无法分辨行为的差异)。

正如您已经发现的那样,您可以强制编译器Observer通过使用完整的对象表达式语法来创建 this 的新实例,这保证每次都有一个新实例。


上述陈述的来源,来自Kotlin in Action一书:

从 Kotlin 1.0 开始,每个 lambda 表达式都被编译成一个匿名类 (...)。如果 lambda 捕获变量,匿名类将为每个捕获的变量提供一个字段,并且将为每次调用创建该类的新实例。否则,将创建一个实例。类的名称是通过从声明 lambda 的函数名称中添加后缀 (...) 来派生的。


推荐阅读