What makes safe call (question mark) to be interpreted differently from classic if?

138 views Asked by At

In Kotlin, if we declare a class member as var and nullable type, compiler doesn't allow us to run the member function although we put an if statement before calling the function because the compiler can't guarantee that the member isn't been set to null after checking against null and before calling the method. But if we are using a safe call compiler approves our code. My question, how the compiler makes the safe call atomic? Isn't a second thread can change the variable between checking for null and calling the method (eat method in the example)? Code for first situation:

        class MyWolf
{
    var w : Wolf? = Wolf()
    
    fun myFunction()
    {
        if (w != null)
        {
            w.eat()
        }
    }

}

class Wolf
{
    fun eat() : Unit
    println("wolf is eating")
}

Code for second situation:

    class MyWolf
{
    var w : Wolf? = Wolf()
        
    fun myFunction()
    {
        w?.eat()
    }
}

class Wolf
{
      fun eat():Unit
    {
        //code
    }
}
1

There are 1 answers

6
Konstantin Raspopov On BEST ANSWER

The compiler puts the contents of the field to the local variable and then compares it with null. You can clearly see it if you decompile Kotlin bytecode.