In Java (and other languages), using null is a common way of indicating that there is no value attached to a reference variable. In Scala, using Option is preferred over using null. Option wraps values that might be null.
None is a subclass of Option wrapping a null reference. Some is a subclass of Option wrapping a non-null reference.
Wrapping a reference is easy:
val nothing = Option(null) // None
val something = Option("Aren't options cool?") // Some("Aren't options cool?")
This is typical code when calling a Java library that might return a null reference:
val resource = Option(JavaLib.getResource())
// if null, then resource = None
// else resource = Some(resource)
If getResource() returns a null value, resource will be a None object. Otherwise it will be a Some(resource) object. The preferred way to handle an Option is using higher order functions available within the Option type. For example if you want to check if your value is not None (similar to checking if value == null), you would use the isDefined function:
val resource: Option[Resource] = Option(JavaLib.getResource())
if (resource.isDefined) { // resource is `Some(_)` type
val r: Resource = resource.get
r.connect()
}
Similarly, to check for a null reference you can do this:
val resource: Option[Resource] = Option(JavaLib.getResource())
if (resource.isEmpty) { // resource is `None` type.
System.out.println("Resource is empty! Cannot connect.")
}
It is preferred that you treat conditional execution on the wrapped value of an Option (without using the 'exceptional' Option.get method) by treating the Option as a monad and using foreach:
val resource: Option[Resource] = Option(JavaLib.getResource())
resource foreach (r => r.connect())
// if r is defined, then r.connect() is run
// if r is empty, then it does nothing
If a Resource instance is required (versus an Option[Resource] instance), you can still use Option to protect against null values. Here the getOrElse method provides a default value:
lazy val defaultResource = new Resource()
val resource: Resource = Option(JavaLib.getResource()).getOrElse(defaultResource)
Java code won't readily handle Scala's Option, so when passing values to Java code it is good form to unwrap an Option, passing null or a sensible default where appropriate:
val resource: Option[Resource] = ???
JavaLib.sendResource(resource.orNull)
JavaLib.sendResource(resource.getOrElse(defaultResource)) //