Akka mapTo versus asInstanceOf

akka, future, scala

Solution

The problem with `asInstanceOf` here is, that it will simply cast to anything you want

scala> val f = future { 2 }
f: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@69b28a51

scala> f.asInstanceOf[Future[String]]
res9: scala.concurrent.Future[String] = scala.concurrent.impl.Promise$DefaultPromise@69b28a51

scala> f.asInstanceOf[Future[List[String]]]
res10: scala.concurrent.Future[List[String]] = scala.concurrent.impl.Promise$DefaultPromise@69b28a51

scala> res10.value
res15: Option[scala.util.Try[List[String]]] = Some(Success(2))

Because of the type erasure the jvm does not know the concrete inner type of the value. If you use `mapTo` instead, it will cast directly on the value, once it is available and in case of a non-matching type, you will get a failed future back.

scala> f.mapTo[List[String]]
res11: scala.concurrent.Future[List[String]] = scala.concurrent.impl.Promise$DefaultPromise@2828afbb


scala> res11.value
res14: Option[scala.util.Try[List[String]]] = Some(Failure(java.lang.ClassCastException:
 Cannot cast java.lang.Integer to scala.collection.immutable.List))

Problem

I'm reading the Akka Futures Guide and I see this sentence: Also note that the Future returned by an Actor is a Future[Any] since an Actor is dynamic. That is why the asInstanceOf is used in the above sample. When using non-blocking it is better to use the mapTo method to safely try to cast a Future to an expected type Why is mapTo better to use than asInstanceOf for a non-blocking Future?

Original source