Lets say I have an array like this*:
val foo: Any = 1 : Int
Option(foo.asInstanceOf[String])
which fails for obvious reason:
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
Next lets consider a following class:
case class DummyRow() {
val foo: Any = 1 : Int
def getAs[T] = foo.asInstanceOf[T]
def getAsOption[T] = Option(foo.asInstanceOf[T])
}
As far as I can tell getAs
should behave the same way as the previous apply
followed by asInstanceOf
.
Surprisingly it is not the case. When called alone it throws an exception:
DummyRow().getAs[String]
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
but when wrapped with Option
succeeds:
val stringOption = Option(DummyRow().getAs[String])
// Option[String] = Some(1)
DummyRow().getAsOption[String]
// Option[String] = Some(1)
and fails only when I try to access wrapped value:
stringOption.get
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
So what happens here? It seems to be limited ClassCastException
so I guess it is related to some ugly thing like type erasure.
* Any
and asInstanceOf
are there to mimic a behavior of the 3rd party code so please lets not dwell on that.
** Tested in Scala 2.10.5, 2.11.7
*** If you're interested in the context you can take a look at Using contains in scala - exception
**** Other relevant questions linked in the comments:
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…