How to determine the class of a Scala object (getClass)

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.