The following function is part of some code I have to interface with a particularly nasty (as in untyped) Java API. It is intended to safely perform casts where the context 'knows' what the type should be, but I want to make sure I won't have bad failure modes in some unknown edge case at runtime:
def safeCast[A](o: Any): Option[A] =
Try(o.asInstanceOf[A]).toOption
Now look what happens when it's used in a REPL session:
scala> val testDouble: Double = 1.0
testDouble: Double = 1.0
scala> safeCast[Int](testDouble)
res0: Option[Int] = Some(1.0)
res0
claims to have type Option[Int]
but value Some(1.0)
(i.e. - Some[Double]
). A class cast exception follows if we try to map over this Option.
This behavior only happens with a polymorphic safeCast
. If we tighten to a specific type:
def safeIntCast(o: Any): Option[Int] = Try(o.asInstanceOf[Int]).toOption
then we get:
scala> safeIntCast(testDouble)
res1: Option[Int] = None
Hence the polymorphism is somehow interacting with the boxing (I suspect??) or with a compiler issue (bug??). The compiler version used was 2.12.2
Can anyone provide an explanation for this?
Please, see here and here for further reference. It explains a lot about Scala asInstanceOf.
Hope it helps!