How to cast a Scala object from one type to another (object casting)

This is an excerpt from the 1st Edition of the Scala Cookbook (partially modified for the internet). This is Recipe 6.1, “How to cast an object from one type to another (object casting).”

Problem

You need to cast an instance of a Scala class from one type to another, such as when creating objects dynamically.

Solution

Use Scala’s asInstanceOf method to cast an instance to the desired type. In the following example, the object returned by the lookup method is cast to an instance of a class named Recognizer:

val recognizer = cm.lookup("recognizer").asInstanceOf[Recognizer]

This Scala code is equivalent to the following Java code:

Recognizer recognizer = (Recognizer)cm.lookup("recognizer");

The asInstanceOf method is defined in the Scala Any class and is therefore available on all objects.

Discussion

In dynamic programming, it’s often necessary to cast from one type to another. This approach is needed when using the Spring Framework and instantiating beans from an application context file:

// open/read the application context file
val ctx = new ClassPathXmlApplicationContext("applicationContext.xml")

// instantiate our dog and cat objects from the application context
val dog = ctx.getBean("dog").asInstanceOf[Animal]
val cat = ctx.getBean("cat").asInstanceOf[Animal]

It’s used when reading a YAML configuration file:

val yaml = new Yaml(new Constructor(classOf[EmailAccount]))
val emailAccount = yaml.load(text).asInstanceOf[EmailAccount]

The example shown in the Solution comes from code I wrote to work with an open source Java speech recognition library named Sphinx-4. With this library, many properties are defined in an XML file, and then you create recognizer and microphone objects dynamically. In a manner similar to Spring, this requires reading an XML configuration file, then casting instances to the specific types you want:

val cm = new ConfigurationManager("config.xml")

// instance of Recognizer
val recognizer = cm.lookup("recognizer").asInstanceOf[Recognizer]

// instance of Microphone
val microphone = cm.lookup("microphone").asInstanceOf[Microphone]

The asInstanceOf method isn’t limited to only these situations. You can use it to cast numeric types:

scala> val a = 10
a: Int = 10

scala> val b = a.asInstanceOf[Long]
b: Long = 10

scala> val c = a.asInstanceOf[Byte]
c: Byte = 10

It can be used in more complicated code, such as when you need to interact with Java and send it an array of Object instances:

val objects = Array("a", 1)
val arrayOfObject = objects.asInstanceOf[Array[Object]]
AJavaClass.sendObjects(arrayOfObject)

It’s demonstrated in Chapter 15 like this:

import java.net.{URL, HttpURLConnection}
val connection = (new URL(url)).openConnection.asInstanceOf[HttpURLConnection]

Be aware that as with Java, this type of coding can lead to a ClassCastException, as demonstrated in this REPL example:

scala> val i = 1
i: Int = 1

scala> i.asInstanceOf[String]
ClassCastException: java.lang.Integer cannot be cast to java.lang.String

As usual, use a try/catch expression to handle this situation.

See Also