Use asInstanceOf[T] carefully!

BackgroundScala 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. …

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

# CodeCode with tests is available on

[GitHub][2]
You May Also Like

New HTTP Logger Grails plugin

I've wrote a new Grails plugin - httplogger. It logs:

  • request information (url, headers, cookies, method, body),
  • grails dispatch information (controller, action, parameters),
  • response information (elapsed time and body).

It is mostly useful for logging your REST traffic. Full HTTP web pages can be huge to log and generally waste your space. I suggest to map all of your REST controllers with the same path in UrlMappings, e.g. /rest/ and configure this plugin with this path.

Here is some simple output just to give you a taste of it.

17:16:00,331 INFO  filters.LogRawRequestInfoFilter  - 17:16:00,340 INFO  filters.LogRawRequestInfoFilter  - 17:16:00,342 INFO  filters.LogGrailsUrlsInfoFilter  - 17:16:00,731 INFO  filters.LogOutputResponseFilter  - >> #1 returned 200, took 405 ms.
17:16:00,745 INFO filters.LogOutputResponseFilter - >> #1 responded with '{count:0}'
17:18:55,799 INFO  filters.LogRawRequestInfoFilter  - 17:18:55,799 INFO  filters.LogRawRequestInfoFilter  - 17:18:55,800 INFO  filters.LogRawRequestInfoFilter  - 17:18:55,801 INFO  filters.LogOutputResponseFilter  - >> #2 returned 404, took 3 ms.
17:18:55,802 INFO filters.LogOutputResponseFilter - >> #2 responded with ''

Official plugin information can be found on Grails plugins website here: http://grails.org/plugins/httplogger or you can browse code on github: TouK/grails-httplogger.

OVal – validate your models quickly and effortlessly!

Some time ago one of the projects at work required me to validate some Java POJOs. Theses were my model classes and I've been creating them from incoming WebService requests. One would say that XSD would be sufficient for the task, for parts of this va...Some time ago one of the projects at work required me to validate some Java POJOs. Theses were my model classes and I've been creating them from incoming WebService requests. One would say that XSD would be sufficient for the task, for parts of this va...