两个观测值指向相同的参考

时间:2019-01-28 10:04:41

标签: java android kotlin

我编写了以下示例,并检查了对象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?) {

    }
}

2 个答案:

答案 0 :(得分:6)

使用此语法时,您要定义一个空主体的lambda:

Observer<String>{}

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

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


来自Kotlin in Action书的上述声明的来源:

  

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

答案 1 :(得分:0)

如果Test类是一个单例,例如在匕首中使用(依赖注入),它将仅被初始化一次,第二次它将指向同一对象。

https://en.wikipedia.org/wiki/Singleton_pattern