Monday, 15 September 2014

Use asInstanceOf[T] carefully!

Background

Scala has nice static type checking engine but from time to time there are situations when we must downcast some general object. If this casting is not possible we expect that virtual machine will throw ClassCastExeption as fast as possible. Although it is not always true. Consider code below.

Suprisingly when we run this test we will see:

Solution

Why this happens? Because type T is erasured during compile. The problem is that compiler doesn't warn about it. Method asInstanceOf[T] is treated as any other regular generic method. If we want to be noticed about type erasure we should use pattern matching:

And then during compilation we will see:

But how to fix this? We can provide implicit evidence parameter:

But we will still have no error if we cast value to generic type e.g.:

With help comes shapeless with Type safe cast. Using this approach casting will be available in compile time only when exists evidence how it is possible.

Summary

Summarizing:

Use pattern matching instead of asInstanceOf[T]

If you are using asInstanceOf[T] make sure that target type is not erasured

Use ClassTag implicit evidence parameter if you are casting only to not generic types