Home > Enterprise >  Scala: if a client val is lazy, but if it's not called, and .close() is executed, will it throw
Scala: if a client val is lazy, but if it's not called, and .close() is executed, will it throw

Time:06-15

If a client val is lazy, but it's not called, and .close() is executed, will it throw an error? Example:

private lazy val cloudWatchClient = CloudWatchClient.builder.region(region).build

cloudWatchClient isn't called.

Later, we'll attempt to close it

try {
cloudWatchClient.close()
}

Does this mean the cloudWatchClient client will open and then closed every time if it's not called at line cloudWatchClient.close()?

CodePudding user response:

No, it will not throw an error (unless you implemented CloudWatchClient to do that on purpose when being initialized). When you prefix a val definition with a lazy modifier, the initializing expression on the right-hand side will only be evaluated the first time the val is used.

Here's a nice example that shows the difference. First a normal object:

scala> object SomeObj {
         val x = {
           println("initializing x")
           "done"
         }
       }
defined object SomeObj

scala> SomeObj
initializing x
val res0: SomeObj.type = SomeObj$@7c3c3d67

scala> SomeObj.x
val res1: String = done

Now an object containing a lazy val:

scala> object SomeLazyObj {
         lazy val x = {
           println("initializing lazy x")
           "done"
         }
       }
defined object SomeLazyObj


scala> SomeLazyObj
val res2: SomeLazyObj.type = SomeLazyObj$@3e4636c3

scala> SomeLazyObj.x
initializing lazy x
val res3: String = done

You can probably now figure that intuitively what lazy does in your example is to avoid initializing cloudWatchClient on the spot. In fact, its initialization happens exactly before close() is called, since operands are evaluated left-to-right, and the method close() needs cloudWatchClient initialized before it can itself be called.

It is worth noting that unlike a def, a lazy val is never evaluated more than once. After the first evaluation of the lazy val, the result is stored, to be reused when the same val is used subsequently.

However, there is one trick to it: if during the first evaluation of your lazy val you get an Exception, the next time you will try to access the lazy val, it will try to re-evaluate itself.

  • Related