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
  • Use shapeless Typeable in all other situations

Code

Code with tests is available on GitHub

No comments:

Post a Comment