Why can't Kotlin variables assigned from fields change in function?

Viewed 26

I'm trying to understand why can't a variable that is assigned from a class field change in a function. Consider this example:

class A {
    private var a: String? = "a"

    fun hello() {
        val b = a

        if (b != null) {
            // The compiler assumes that 'b' is always not null inside this branch

            b.length
        } else {
            // is null
        }
    }
}

Variable b is going to always be the same throughout the function (later is implicit non null in the if branch). So even if through concurrency I change the field a, the variable b does not change?

How is this possible? does Kotlin make a copy of the variable and assigns it to b? I thought assignments worked with references and such.

This can happen, as far as I'm concerned, with any type (String, Int, custom class, etc)

1 Answers

Strings are immutable, there's no way you can change them after you instantiated them. Thus, if another thread modifies the value of a after b != null was evaluated, it will not affect b's value.

Actually it's not even the real answer because here we're just talking about nullity. b will point to whatever object was pointed by a at the moment of the assignment, but then nothing can change what b is pointing to because b is a val.

I was just mentioning immutability because the content of b could still change through mutation if the type was mutable, but the reference itself will never change.

For more clarity, let's make a scenario:

[thread 1] a = "hello" <state: a => h: String("hello")>
[thread 1] b = a <state: a => h, b => h>
[thread 2] a = "world" <state: a => w: String("world"), b => h>

In short, b points to the same object as a at the time of assignment, but it doesn't point to a itself, so when a changes, b doesn't care.

Related