Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin variable initialization for child class behaves weird for initializing variable with value 0

I have created the following class hierarchy:

open class A {
    init {
        f()
    }

    open fun f() {
        println("In A f")
    }
}

class B : A() {
    var x: Int = 33

    init {
        println("x: " + x)
    }

    override fun f() {
        x = 1
        println("x in f: "+ x)
    }

    init {
        println("x2: " + x)
    }
}

fun main() {
    println("Hello World!!")
    val b = B()
    println("in main x : " + b.x)
}

The output of this code is

Hello World!!
x in f: 1
x: 33
x2: 33
in main x : 33

But if I change the initialization of x from

var x: Int = 33

to

var x: Int = 0

the output shows the invocation of the method in contrast to the output above:

Hello World!!
x in f: 1
x: 1
x2: 1
in main x : 1

Does anyone know why the initialization with 0 causes a different behaviour than the one with another value?

like image 787
PRATYUSH SINGH Avatar asked Jan 20 '20 11:01

PRATYUSH SINGH


People also ask

Do you have to initialize variables in Kotlin?

The var keyword lets you create a variable whose reference will be mutable (which can be modified after its initialization). Kotlin does not require you to mention the type of a variable when declaring it (thanks to type inference). A variable val must be initialized in the same block of code in which it was declared.

How do you initialize a value in Kotlin?

To initialize a String variable in Kotlin, we may assign the String literal to the variable without specifying explicit type, or we may declare a variable of type String and assign a String literal later.

How do you declare an empty variable in Kotlin?

To create an empty String in Kotlin, assign the variable with empty double quotes "" , or with String class constructor String() .

How do you declare a class variable in Kotlin?

Kotlin uses two different keywords to declare variables: val and var . Use val for a variable whose value never changes. You can't reassign a value to a variable that was declared using val . Use var for a variable whose value can change.


1 Answers

super class is initialized before sub class.

The constructor call of B calls the constructor of A, which calls the function f printing "x in f: 1", after A is initialized, the rest of B is initialized.

So essentially, the setting of the value is being overwritten.

(When you initialize primitives with their zero value in Kotlin, they technically just dont initialize at all)

You can observe this "overwrite" behavior by changing the signature from

var x: Int = 0 to var x: Int? = 0

Since x is no longer the primitive int, the field actually gets initialized to a value, producing the output:

Hello World!!
x in f: 1
x: 0
x2: 0
in main x : 0
like image 86
Sxtanna Avatar answered Oct 15 '22 06:10

Sxtanna