Two observables point to the same reference

pistolcaffe :

I wrote the following example and checked the value of the observerA variable for objects a and b.

Example

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

Check

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

Result

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

My guess is that a.observerA and a.observerA should be different, but they refer to the same object.

When I wrote observerA as below, I saw that different objects were created. I do not know why this difference appears.

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

    }
}
zsmb13 :

When you use this syntax, you're defining a lambda with an empty body:

Observer<String>{}

This lambda will be compiled down to an anonymous class. If the lambda doesn't capture any variables, as an optimization step, there'll only be one instance of it (since you can't tell the difference in behaviour anyway).

As you've discovered already, you can force the compiler to create new instances of this Observer by using the full object expression syntax, which guarantees a new instance every time.


Source for the statements above, from the Kotlin in Action book:

As of Kotlin 1.0, every lambda expression is compiled into an anonymous class (...). If a lambda captures variables, the anonymous class will have a field for each captured variable, and a new instance of that class will be created for every invocation. Otherwise, a single instance will be created. The name of the class is derived by adding a suffix from the name of the function in which the lambda is declared (...).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=115311&siteId=1