3.17. Declaring a Variable Before Using It in a try/catch/finally Block

Problem

You want to use an object in a try block, and need to access it in the finally portion of the block, such as when you need to call a close method on an object.

Solution

In general, declare your field as an Option before the try/catch block, then create a Some inside the try clause. This is shown in the following example, where the fields in and out are declared before the try/catch block, and assigned inside the try clause:

import java.io._

object CopyBytes extends App {

  var in = None: Option[FileInputStream]
  var out = None: Option[FileOutputStream]

  try {
    in = Some(new FileInputStream("/tmp/Test.class"))
    out = Some(new FileOutputStream("/tmp/Test.class.copy"))
    var c = 0
    while ({c = in.get.read; c != 1}) {
      out.get.write(c)
    }
  } catch {
    case e: IOException => e.printStackTrace
  } finally {
    println("entered finally ...")
    if (in.isDefined) in.get.close
    if (out.isDefined) out.get.close
  }

}

In this code, in and out are assigned to None before the try clause, and then reassigned to Some values inside the try clause if everything succeeds. Therefore, it’s safe to call in.get and out.get in the while loop, because if an exception had occurred, flow control would have switched to the catch clause, and then the finally clause before leaving the method.

Normally I tell people that I wish the get and isDefined methods on Option would be deprecated, but this is one of the few times where I think their use is acceptable, ...

Get Scala Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.