Почему перенос обобщенного вызова метода с помощью Option откладывает ClassCastException?
Допустим, у меня есть такой массив *:
val foo: Any = 1 : Int
Option(foo.asInstanceOf[String])
который терпит неудачу по очевидной причине:
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
Далее давайте рассмотрим следующий класс:
case class DummyRow() {
val foo: Any = 1 : Int
def getAs[T] = foo.asInstanceOf[T]
def getAsOption[T] = Option(foo.asInstanceOf[T])
}
Насколько я могу судитьgetAs
должен вести себя так же, как предыдущийapply
с последующимasInstanceOf
.
Удивительно, но это не так. При вызове в одиночку выдает исключение:
DummyRow().getAs[String]
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
но когда завернутый сOption
преуспевает:
val stringOption = Option(DummyRow().getAs[String])
// Option[String] = Some(1)
DummyRow().getAsOption[String]
// Option[String] = Some(1)
и терпит неудачу только когда я пытаюсь получить доступ к упакованному значению:
stringOption.get
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
Так что здесь происходит? Кажется ограниченнымClassCastException
так что я думаю, что это связано с какой-то уродливой вещью типа стирания типа.
* Any
а такжеasInstanceOf
чтобы имитировать поведение стороннего кода, поэтому давайте не будем останавливаться на этом.
** Проверено в Scala 2.10.5, 2.11.7
*** Если вы заинтересованы в контексте, вы можете взглянуть наИспользование содержит в Scala - исключение
**** Другие актуальные вопросы, связанные в комментариях:
Почему `.asInstanceOf` иногда выбрасывает, а иногда нет?,Почему asInstanceOf не генерирует исключение ClassCastException?