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.
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |
See Also
- Recipe 2.2, “Converting Between Numeric Types (Casting)”, for more numeric type casting recipes.
- The Scala Any class
- The Sphinx-4 project