Вот надуманные эксперименты в REPL (scala 2.11):
scala> class Foo[T] {
| def as(x: Any) = x.asInstanceOf[T]
| }
defined class Foo
scala> val foo = new Foo[String]
foo: Foo[String] = Foo@65ae6ba4
scala> val x: Any = 123
x: Any = 123
scala> foo.as(x) // expected
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
... 33 elided
scala> val y: Any = "abc"
y: Any = abc
scala> foo.as(y)
res1: String = abc
scala> class Bar[T] {
| def is(x: Any) = x.isInstanceOf[T]
| }
<console>:12: warning: abstract type T is unchecked since it is eliminated by erasure
def is(x: Any) = x.isInstanceOf[T]
^
defined class Bar
scala> val bar = new Bar[String]
foo: Foo[String] = Foo@1753acfe
scala> val x: Any = 123
x: Any = 123
scala> bar.is(x) // unexpected
res2: Boolean = true
scala> val y: Any = "abc"
y: Any = abc
scala> bar.is(y)
res3: Boolean = true
Я знаю, что параметр типа довольно ограничен из-за стирания типа, но все еще смущен различным поведением между asInstanceOf и isInstanceOf здесь.
Интересно, есть ли у кого-нибудь представление об этом? Спасибо!
true
/false
(в вашем случае всегдаtrue
, потому что x имеет типAny
), asInstanceOf на самом деле пытается выполнить приведение вашей переменной к типу, который вы хотели, и, следовательно,java.lang.ClassCastException
. На самом деле оба могут получить параметрыType
, но кастинг должен быть законным. - person Avihoo Mamka   schedule 10.12.2015asInstanceOf
и посмотреть, получится ли. ПочемуisInstanceOf
не реализован таким образом? - person n. 1.8e9-where's-my-share m.   schedule 10.12.2015instanceof
. ТехническиisInstanceOf
является частью отражения Java, где оно известно какinstanceof
. - person Avihoo Mamka   schedule 10.12.2015asInstanceOf
всегда будет успешным, пока вы не попытаетесь использовать его как неправильный тип, но нет универсального способа узнать это во время выполнения. То есть каждый тип терпит неудачу по-своему. - person Michael Zajac   schedule 10.12.2015