1

Given the code below:

class Foo {
    companion object {
        lateinit var names: Array<String>
    }
    init {
        names = arrayOf("George", "Keith", "Martha", "Margret")
    }

}

If I created two instances of Foo:

var foo1 = Foo();
var foo2 = Foo();

is names going to be initialised/assigned twice, and therefore with any subsequent Foo initialisation?

My intent is to have a simple static variable names holding those predefined names.

Update:

This is assuming I do not want to have: var names: arrayOf("George", "Keith", "Martha", "Margret") inside companion object.

pnizzle
  • 6,243
  • 4
  • 52
  • 81
  • @JeelVankhede Ive just updated my question. I knew someone would jump to that. – pnizzle Dec 31 '19 at 09:12
  • I assume you guys are agreeing that each time init is called, names is assigned a new instance of the array? – pnizzle Dec 31 '19 at 09:13
  • 1
    Yes, one other thing you can try is take your initialization to another object as local variable then use that to assign your companion variable. – Jeel Vankhede Dec 31 '19 at 09:15

4 Answers4

3

is names going to be initialised/assigned twice, and therefore with any subsequent Foo initialisation?

As in init block its initializing names every time so it will create new Array for every instance.

You can verify this with simple print

class Foo {
    companion object {
        lateinit var names: Array<String>
    }
    init {
        println("Creating Foo")
        names = arrayOf("George", "Keith", "Martha", "Margret")
    }

    fun getHashCode():Int{
        return names.hashCode()
    }

}

fun main() {

    var foo1 = Foo();
    println(foo1.getHashCode());
    var foo2 = Foo();
    println(foo2.getHashCode());
}

In Output HashCode are different :

Creating Foo
746292446
Creating Foo
1072591677
Abu Yousuf
  • 5,729
  • 3
  • 31
  • 50
1

You can try below code block to achieve what you want.

class Foo {

    object ArrayOfString {
        val names = arrayOf("George", "Keith", "Martha", "Margret")
    }

    companion object {
        val names: Array<String> = ArrayOfString.names
    }
}

By this way, you won't have initialization every time for your array, hope that make sense!

Jeel Vankhede
  • 11,592
  • 2
  • 28
  • 58
  • `object ArrayOfString` is a singleton in Kotlin isn't it? So this is pretty much the same as initialising `names` inside `companion object`. I think just doing that keeps it simple, as I might have over engineered a few things. – pnizzle Dec 31 '19 at 09:23
  • Yes, it's singleton! – Jeel Vankhede Dec 31 '19 at 09:28
0

Companion object in Kotlin works same as the the static in java. By declaring a companion object inside our class, you’ll be able to call its members with the same syntax as calling static methods in Java.And yes its going to be initialized once also in kotlin we have one more keyword for singleton instance to create the singleton in kotlin.

On other hand init is going to called after primary constructor also you can have one or more init blocks executing in series.

haresh
  • 1,424
  • 2
  • 12
  • 18
0
class Foo {
Var names :ArrayList<String> = arrayOf("George", "Keith", "Martha", "Margret")
companion object {
    lateinit var names: Array<String>
}}

You can do like this