4

Having a Scala class with a companion object

object BB {
    val time = System.currentTimeMillis()
}

class BB {
    val time = System.currentTimeMillis()
}

I was wondering if the object was working just like in Java where If I remember the first thing to be evaluated in the class was the statics and then finally the constructor.

But here when I create a new instance of BB and check the times, the object it´s not evaluated first.

object main extends App {
    val time = System.currentTimeMillis()
    private val bb = new BB

    println(s"App:$time ")
    println("Instance" + bb.time )
    println(s"Static ${BB.time }")
}

So then I've been wondering how the initialization in Scala works?

Regards.

4
  • 4
    The companion object is initialized on the first access to it. Commented Apr 2, 2019 at 15:13
  • so just to be 100% sure, only when I invoke BB.time it´s when all that contains the object BB it´s initialized? Thanks a lot Commented Apr 2, 2019 at 15:23
  • 1
    If you mean everything that is contained in BB, then yes, that will be initialized when BB.time is invoked (unless the field is defined as lazy val or def). Commented Apr 2, 2019 at 15:56
  • sure!, so then we can asume object is lazy by design. Thanks a lot for the clarification Commented Apr 2, 2019 at 16:00

1 Answer 1

4

As noted in a comment, companion objects are initialized on the first access to it. More broadly, all objects in Scala are initialized lazily. Quoting the Scala Language Specification (for version 2.12):

Note that the value defined by an object definition is instantiated lazily. The new m$cls constructor is evaluated not at the point of the object definition, but is instead evaluated the first time m is dereferenced during execution of the program (which might be never at all).

You can confirm it with a little experiment (where I'm going to use an Iterator instead of System.currentTimeMillis so that this can be easily hosted and ran on Scastie):

val ticks = Iterator.from(0)

object BB {
  val time = ticks.next()
  val foo = "bar"
}

class BB {
  val time = ticks.next()
}

new BB().time
new BB().time
BB.foo
new BB().time
BB.time

The last five expressions will cause BB (the object) to be initialized when its foo member is accessed, making the very last expression evaluate to 2.

As mentioned before, you can play around with this code on Scastie.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.