Table of Contents
This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 6.3, “How to determine the Class of a Scala object.”
Problem
Because you don’t have to explicitly declare types with Scala, you may occasionally want to print the class/type of an object to understand how Scala works, or to debug code.
Solution
When you want to learn about the types Scala is automatically assigning on your behalf, call the getClass
method on the object.
For instance, when I was first trying to understand how varargs fields work, I called getClass
on a method argument, and found that the class my method was receiving varied depending on the situation. Here’s the method declaration:
def printAll(numbers: Int*) { println("class: " + numbers.getClass) }
Calling the printAll
method with and without arguments demonstrates the two classes Scala assigns to the numbers field under the different conditions:
scala> printAll(1, 2, 3) class scala.collection.mutable.WrappedArray$ofInt scala> printAll() class scala.collection.immutable.Nil$
This technique can be very useful when working with something like Scala’s XML library, so you can understand which classes you’re working with in different situations.
For instance, the following example shows that the <p>
tag contains one child element, which is of class scala.xml.Text:
scala> val hello = <p>Hello, world</p> hello: scala.xml.Elem = <p>Hello, world</p> scala> hello.child.foreach(e => println(e.getClass)) class scala.xml.Text
However, by adding a <br/>
tag inside the <p>
tags, there are now three child elements of two different types:
scala> val hello = <p>Hello, <br/>world</p> hello: scala.xml.Elem = <p>Hello, <br/>world</p> scala> hello.child.foreach(e => println(e.getClass)) class scala.xml.Text class scala.xml.Elem class scala.xml.Text
When you can’t see information like this in your IDE, using this getClass
approach is very helpful.
Discussion
When I can’t see object types in a Scala IDE, I write little tests like this in the REPL. The usual pattern is to call getClass
on the object of interest, passing in different parameters to see how things work:
scala> def printClass(c: Any) { println(c.getClass) } printClass: (c: Any)Unit scala> printClass(1) class java.lang.Integer scala> printClass("yo") class java.lang.String
In the first example shown in the Solution, the types Scala assigns to the number parameter don’t matter too much; it was more a matter of curiosity about how things work. The actual method looks like the following code, and for my purposes, the only important thing is that each class Scala uses supports a foreach
method:
def printAll(numbers: Int*) { numbers.foreach(println) }
As desired, this method can be called with and without parameters:
scala> printAll(1,2,3) 1 2 3 scala> printAll() (no output)
More details
Note that if you need more details than getClass shows, you can add additional methods after it. The comments in the code below show how the additional get*
methods work:
sealed trait Animal class Dog extends Animal class Cat extends Animal object Animal { // factory method def getAnimal(s: String): Animal = if (s == "dog") new Dog else new Cat } object ObjectCastingTest extends App { val animal = Animal.getAnimal("dog") println("animal: " + animal.getClass) // class object_casting.Dog println("animal: " + animal.getClass.getName) // object_casting.Dog println("animal: " + animal.getClass.getSimpleName) // Dog println("animal: " + animal.getClass.getCanonicalName) // object_casting.Dog }
Those examples show how the getName
, getSimpleName
, and getCanonicalName
methods work.
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |