Por que agrupar uma chamada de método genérica com a Option adia o ClassCastException?
Digamos que eu tenho uma matriz como esta *:
val foo: Any = 1 : Int
Option(foo.asInstanceOf[String])
que falha por motivo óbvio:
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
A seguir, vamos considerar uma classe a seguir:
case class DummyRow() {
val foo: Any = 1 : Int
def getAs[T] = foo.asInstanceOf[T]
def getAsOption[T] = Option(foo.asInstanceOf[T])
}
Tanto quanto eu posso dizergetAs
deve se comportar da mesma maneira que o anteriorapply
Seguido porasInstanceOf
.
Surpreendentemente, não é o caso. Quando chamado sozinho, lança uma exceção:
DummyRow().getAs[String]
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
mas quando embrulhado comOption
consegue:
val stringOption = Option(DummyRow().getAs[String])
// Option[String] = Some(1)
DummyRow().getAsOption[String]
// Option[String] = Some(1)
e falha apenas quando tento acessar o valor agrupado:
stringOption.get
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
Então o que acontece aqui? Parece ser limitadoClassCastException
então eu acho que está relacionado a alguma coisa feia como apagamento de tipo.
* Any
easInstanceOf
existem para imitar um comportamento do código de terceiros; portanto, não vamos nos debruçar sobre isso.
** Testado em Scala 2.10.5, 2.11.7
*** Se você está interessado no contexto, pode dar uma olhadaUsando contains na scala - exceção
**** Outras questões relevantes vinculadas nos comentários:
Por que o `.asInstanceOf` às vezes é lançado e às vezes não?,Por que asInstanceOf não lança uma ClassCastException?